使用OpenTracing跟踪Go中的HTTP请求延迟
在Go 1.7,我们有一个新包/ HTTP / httptrace提供了一个方便的机制,观察一个HTTP请求时会发生什么。在本文中,将说明如何能在分布式跟踪的情况下被使用,通过使用OpenTracing API跟踪观察一个客户端和一个服务器,并可视化的结果显示在Zipkin UI 。
什么是分布式跟踪和OpenTracing?
分布式跟踪是监测和分析微服务架构系统,导出结果到为X-TRACE,如谷歌的Dapper和Twitter的Zipkin 。 它们的底层原理是分布式环境传播 ,其中涉及的某些元数据与进入系统的每个请求相关联,并且跨线程和进程边界传播元数据跟随请求进出各种微服务调用。 如果我们为每个入站请求分配一个唯一的ID并将其作为分布式上下文的一部分,那么我们可以将来自多个线程和多个进程的各种性能分析数据合并到统一的表示我们系统执行请求的“跟踪”中。
分布式跟踪需要使用Hook钩子和上下文传播机制来测试应用程序代码(或其使用的框架)。 当我们在Uber开始构建我们的分布式跟踪系统时,我们很快意识到,没有良好的API为开发人员提供在编程语言之间内部一致性,那就无法绑定到指定的跟踪系统。原来,不只是我们有这种思维,2015年10月一个新的社区形成,催生了OpenTracing API,一个开放的,厂商中立的,与语言无关的分布式跟踪标准。你可以阅读更多关于Ben Sigelman有关OpenTracing动机和设计原理背后的文章 。
让我们看看代码:
|
这里有几点要注意:
1.回避了tracer变量初始化的问题。
2.AskGoogle函数接受context.Context对象。这是为开发分布式应用程序的Go推荐方式,因为上下文对象是要让分布式环境传播。
3.我们假设上下文已经包含父跟踪Span。 OpenTracing API中的Span是用于表示由微服务执行的工作单元。HTTP调用就是可以包裹在跟踪Span中的操作案例。 当我们运行处理入站请求的服务时,服务通常会为每个请求创建一个跟踪范围,并将其存储在上下文中,以便在对另一个服务进行下游调用时可用(在我们的示例中为google.com )。
4.我们启动一个新的子Span来包装出站HTTP调用。 如果父Span缺失,这是好方法。
5.最后,在做出HTTP请求之前,我们实例化一个ClientTrace并将其附加到请求。
ClientTrace结构是httptrace的基本构建块 。它允许我们在HTTP请求的生命周期内注册将由HTTP客户端执行的回调函数。 例如,ClientTrace结构有这样的方法:
|
我们在NewClientTrace方法中创建这个结构的一个实例:
|
我们为DBBStart和DNSDone事件实现注册两个回调函数,通过私有结构clientTrace保有一个指向跟踪Span。 在回调方法中,我们使用Span的键值记录API来记录事件的信息,以及Span本身隐含捕获的时间戳。
你不是说关于UI的东西吗?
OpenTracing API的工作方式是,一旦调用跟踪Span的Finish()方法,Span捕获的数据将发送到跟踪系统后端,通常在后台异步发送。然后,我们可以使用跟踪系统UI来查找跟踪并在时间线上将其可视化。 然而,上述例子只是为了说明使用OpenTracing与httptrace的原理。对于真正的工作示例,我们将使用现有的库https://github.com/opentracing-contrib/go-stdlib 。 使用这个库我们的客户端代码不需要担心跟踪实际的HTTP调用。但是,我们仍然希望创建一个顶层跟踪Span来表示客户端应用程序的整体执行,并记录任何错误。
|
上面的客户端代码调用本地服务器。 让我们实现它。
|
注意,客户端向根端点“/”发出请求,但服务器将其重定向到“/ gettime”端点。 这样做允许我们更好地说明如何在跟踪系统中捕获跟踪。
Tracing HTTP request latency in Go with OpenTracin
[该贴被banq于2016-11-25 09:00修改过]