Go 1.7 新功能 HTTP Tracing
Jaana Burcu Dogan
2016年10月4日
介绍
在Go 1.7中,我们引入了HTTP跟踪,这是一种在HTTP客户端请求的整个生命周期中收集细粒度信息的工具。 net / http / httptrace
软件包提供了对HTTP跟踪的支持。收集的信息可用于调试延迟问题,服务监视,编写自适应系统等。
HTTP 事件
httptrace
包提供了许多钩子,以在HTTP往返期间收集有关各种事件的信息。这些事件包括:
-建立连接
-连接重用
-DNS查找
-将请求写入网络
-读回复
跟踪事件
您可以通过将包含钩子函数的*httptrace.ClientTrace
放入请求的context.Context
。各种http.RoundTripper
实现通过查找上下文的*httptrace.ClientTrace
来报告内部事件调用相关的钩子函数。
跟踪的范围取决于请求的上下文,用户在开始请求之前应在请求上下文中放置*httptrace.ClientTrace
。
req, _ := http.NewRequest("GET", "http://example.com", nil)
trace := &httptrace.ClientTrace{
DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
fmt.Printf("DNS Info: %+v.", dnsInfo)
},
GotConn: func(connInfo httptrace.GotConnInfo) {
fmt.Printf("Got Conn: %+v.", connInfo)
},
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
if _, err := http.DefaultTransport.RoundTrip(req); err != nil {
log.Fatal(err)
}
在往返过程中,http.DefaultTransport
将在事件发生时调用每个挂钩。 DNS查找完成后,上述程序将打印DNS信息。建立与请求主机的连接后,它将类似地打印连接信息。
使用http.Client进行跟踪
跟踪机制旨在跟踪单个http.Transport.RoundTrip
生命周期中的事件。但是,客户端可以进行多次往返以完成HTTP请求。例如,在URL重定向的情况下,注册的钩子将与客户端遵循HTTP重定向的次数一样多,从而发出多个请求。用户负责在http.Client
级别识别此类事件。下面的程序通过使用http.RoundTripper
包装器标识当前请求。
package main
import (
"fmt"
"log"
"net/http"
"net/http/httptrace"
)
// transport 是一个http.RoundTripper,它可以实时跟踪
// request 并实现钩子以报告HTTP跟踪事件
type transport struct {
current *http.Request
}
// RoundTrip 包装了http.DefaultTransport.RoundTrip以保持对当前请求的跟踪
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
t.current = req
return http.DefaultTransport.RoundTrip(req)
}
// GotConn 打印对当前请求以前是否使用过连接
func (t *transport) GotConn(info httptrace.GotConnInfo) {
fmt.Printf("Connection reused for %v? %v.", t.current.URL, info.Reused)
}
func main() {
t := &transport{}
req, _ := http.NewRequest("GET", "https://google.com", nil)
trace := &httptrace.ClientTrace{
GotConn: t.GotConn,
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
client := &http.Client{Transport: t}
if _, err := client.Do(req); err != nil {
log.Fatal(err)
}
}
该程序将跟随google.com重定向到www.google.com 并输出:
Connection reused for https://google.com? false
Connection reused for https://www.google.com/? false
net / http
包中的传输支持对HTTP / 1和HTTP / 2请求的跟踪。
如果您是自定义http.RoundTripper
实现的作者,则可以通过检查*httptest.ClientTrace
的请求上下文并在事件发生时调用相关的挂钩来支持跟踪。
结论
对于那些对调试HTTP请求延迟和编写用于出站流量的网络调试工具感兴趣的人,HTTP跟踪是Go的宝贵补充。通过启用此新功能,我们希望看到社区中的HTTP调试,基准测试和可视化工具-例如httpstat。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。