Go 1.7 新功能 HTTP Tracing

未匹配的标注

本文为官方 Go Blog 的中文翻译,详见 翻译说明

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

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/go-blog/http-tr...

译文地址:https://learnku.com/docs/go-blog/http-tr...

上一篇 下一篇
Summer
贡献者:1
讨论数量: 0
发起讨论 查看所有版本


暂无话题~