2019独角兽企业重金招聘Python工程师标准>>>

在微服务领域,分布式跟踪正逐渐成为调试和跟踪应用程序最重要的依赖工具。

最近的聚会和会议上,我发现很多人对分布式跟踪的工作原理很感兴趣,但同时对于分布式跟踪如何与Istio和Aspen Mesh等服务网格进行配合使用存在较大的困惑。特别地,我经常被问及以下问题:

  • Tracing如何与Istio一起使用?在Span中收集和报告哪些信息?
  • 是否必须更改应用程序才能从Istio的分布式跟踪中受益?
  • 如果目前在应用程序中报告Span,它将如何与Istio中的Span进行交互?

在这篇博客中,我将尝试回答这些问题。

在我们深入研究这些问题之前,建议先快速了解为什么我要写与分布式跟踪相关博客。如果您关注Aspen Mesh的博客,您会注意到我写了两篇与tracing相关的博客,一篇关于 ”使用Istio跟踪AWS中的服务请求“,另一篇关于”使用Istio跟踪gRPC应用程序”。

我们在Aspen Mesh有一个非常小的工程团队,如果经常在子系统或组件上工作,您很快就会成为(或标记或分配)常驻专家。我在微服务中添加了分布式跟踪,并在AWS环境中将其与Istio集成,在此过程中发现了值得分享的各种有趣的经验。在过去的几个月里,我们一直在大量使用跟踪来了解我们的微服务,现在这种方法已经成为我们排查问题首先采用的手段。后续,我们继续回答上面提到的问题。

Tracing如何与Istio一起使用?

Istio在应用程序运行的Pod容器中注入sidecar代理(Envoy)。sidecar代理透明地拦截(防火墙魔法)进出应用程序的所有网络流量。拦截模式下,sidecar代理处于一个独特的位置,可以自动跟踪所有网络请求(包括HTTP/1.1、HTTP/2.0和gRPC)。

让我们看看sidecar代理对来自客户端(外部或其他微服务)的传入Pod请求所做的更改。从现在开始,为了简单起见,我将假设跟踪标头采用Zipkin格式。

  • 如果传入请求没有任何跟踪头,则在请求传递到与sidecar同一Pod中的应用程序容器前,sidecar代理将创建根Span(其中trace、parent和Span ID具有完全相同的Span)。
  • 如果传入的请求有跟踪信息(如正在使用Istio Ingress或者微服务是从另一个注入了sidecar代理的微服务中调用),那么sidecar代理将从跟踪头中提取Span上下文,在将请求传递到同一Pod中的应用程序容器之前,创建一个新的兄弟(sibling)Span(与传入头相同的trace、parent和Span ID)。

在应用程序容器发出相反方向上的出站请求(外部服务或集群中的服务)时,Pod中的sidecar代理在向上游服务发出请求之前执行以下操作:

  • 如果不存在跟踪头,则sidecar代理会创建根Span并将Span上下文作为头部注入新请求。
  • 如果存在跟踪头,则sidecar代理从头部中提取Span上下文,并基于此上下文创建子Span。新上下文作为请求中的跟踪头传播到上游服务。

根据上面的解释,您应该注意到对于微服务调用链中的每一跳,将获得Istio报告的两个Span,一个来自客户端sidecar(span.kind设置为client)和一个来自服务器sidecar(span.kind设置为server)。sidecar创建的所有Span都由sidecar自动报告给配置的后端跟踪系统,比如Jaeger或Zipkin等。

接下来,让我们看一下Span中报告的信息。Span包含以下信息:

  • x-request-id:报告为 guid:x-request-id,这对于将访问日志与Span相关联非常有用。
  • upstream cluster:发出请求的上游服务。如果Span跟踪对Pod的传入请求,则通常将其设置为 in.<name>。如果Span跟踪出站请求,则将其设置为 out.<name>
  • HTTP headers:在可用时报告以下 HTTP 头部信息:
    • +URL
    • +Method
    • +User 代理
    • +Protocol
    • +Request 大小
    • +Response 大小
    • +Response 标记
  • 每个Span的开始和结束时间。
  • 跟踪的元数据:这包括trace ID、Span ID和Span类型(client或server)。除此之外,还会报告每个Span的操作名称。操作名称设置为影响路由配置的虚拟服务(或 v1alpha1 中的路由规则),如果选择了默认路由,则设置为 “default-route”。这对于了解哪个Istio路由配置对Span生效非常有用。

接下来让我们继续讨论第二个问题。

是否必须修改应用程序才能利用Istio追踪?

是的,您需要在应用程序中添加逻辑,以便将传入跟踪头部信息从传入请求传播到传出请求,这样才能从Istio的分布式跟踪中获得更多有价值的信息。

如果应用程序容器在传入请求的上下文中发出新的出站请求,且传入请求中未包括跟踪头,则sidecar代理会为出站请求创建根Span。这意味着您将始终只看到两个微服务的路径。另一方面,如果应用程序容器确实将跟踪头部信息从传入请求传播到传出请求,则sidecar代理将创建如上所述的子Span。通过创建子Span,您可以了解跨多个微服务的依赖关系。

在应用程序中传播跟踪头有两种选择。

  1. 查找Istio文档中提到的跟踪头,并将其从传入请求传输到传出请求。这种方法很简单,几乎适用于所有情况。但是,它有一个主要缺点,无法向Span添加自定义标记信息例如用户信息等。您无法创建应用程序中的事件相关的子Span。由于是在不了解Span格式或上下文的情况下传播跟踪信息,因此添加特定于应用程序的信息的能力有限。
  2. 第二种方法是在应用程序中设置跟踪客户端,并使用Opentracing API将跟踪头部信息从传入请求传播到传出请求。我创建了一个跟踪示例包,它提供了一种在您的应用程序中设置jaeger-client-go的简单方法,该方法与Istio兼容。以下代码段可用于应用程序的主功能中:
import ("log""github.com/spf13/cobra""github.com/spf13/viper""github.com/aspenmesh/tracing-go"
)func setupTracing() {// Configure TracingtOpts := &tracing.Options{ZipkinURL: viper.GetString("trace_zipkin_url"),JaegerURL: viper.GetString("trace_jaeger_url"),LogTraceSpans: viper.GetBool("trace_log_spans"),}if err := tOpts.Validate(); err != nil {log.Fatal("Invalid options for tracing: ", err)}var tracer io.Closerif tOpts.TracingEnabled() {tracer, err = tracing.Configure("myapp", tOpts)if err != nil {tracer.Close()log.Fatal("Failed to configure tracing: ", err)} else {defer tracer.Close()}}
}

需要注意的关键点是在tracing-go包中我将Opentracing全局跟踪器设置Jaeger。 这使我能够使用Opentracing API将跟踪头从传入请求传播到传出请求,如下所示:

import ("net/http""golang.org/x/net/context""golang.org/x/net/context/ctxhttp"ot "github.com/opentracing/opentracing-go"
)func injectTracingHeaders(incomingReq *http.Request, addr string) {ifSpan:= ot.SpanFromContext(incomingReq.Context());Span!= nil {outgoingReq, _ := http.NewRequest("GET", addr, nil)ot.GlobalTracer().Inject(span.Context(),ot.HTTPHeaders,ot.HTTPHeadersCarrier(outgoingReq.Header))resp, err := ctxhttp.Do(ctx, nil, outgoingReq)// Do something with resp}
}

您还可以使用Opentracing API 来设置Span标记或从Istio添加的跟踪上下文创建子Span,如下所示:

func SetSpanTag(incomingReq *http.Request, key string, value interface{}) {ifSpan:= ot.SpanFromContext(incomingReq.Context());Span!= nil {span.SetTag(key, value)}
}

除了上述好处之外,您不必直接处理跟踪信息,但跟踪器(在本例中为Jaeger)会为您处理它。 我强烈建议使用此方法,因为它在应用程序中提供了跟踪的基础,增强了跟踪功能而不会产生太多开销。

现在让我们继续讨论第三个问题。

Istio报告的Span如何与应用程序创建的Span交互?

如果您希望应用程序报告的Span是Istio添加的跟踪上下文的子Span,则应使用OpenTracing API StartSpanFromContext而不是使用StartSpan。如果存在跟踪头部信息,则StartSpanFromContext从父级上下文创建子Span,否则创建根Span。

请注意,在上面的所有示例中,我都使用了OpenTracing Go API,但您应该能够使用与应用程序相同语言编写的任何跟踪客户端库,只要它与OpenTracing API兼容即可。

转载于:https://my.oschina.net/xiaominmin/blog/1863870

使用Istio分布式跟踪应用程序相关推荐

  1. 云原生 - Istio可观察性之分布式跟踪(三)

    作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...

  2. 分布式 开源_3个开源分布式跟踪工具

    分布式 开源 分布式跟踪系统使用户可以通过分布在多个应用程序,服务和数据库以及诸如代理之类的中介中的软件系统跟踪请求. 这样可以更深入地了解软件系统中正在发生的事情. 这些系统产生图形表示,这些图形表 ...

  3. 分布式链接跟踪服务_微服务世界中的分布式跟踪

    分布式链接跟踪服务 微服务已成为未开发应用程序的默认选择. 毕竟,从业人员认为,微服务提供了完全数字化转型所需的解耦类型,从而使各个团队的创新速度比以往任何时候都快. 微服务只不过是常规的分布式系统, ...

  4. 以Dapper、Zipkin和LightStep [x]PM为例阐述分布式跟踪的过去、现在和未来

    \ 核心要点 \\ 在观测分布式系统和微服务时,分布式跟踪已经成为一个越来越重要的组件.现在有一些流行的开源标准和框架,比如OpenTracing API和OpenZipkin:\\t 分布式跟踪的基 ...

  5. Ocelot 集成Butterfly 实现分布式跟踪

    微服务,通常都是用复杂的.大规模分布式集群来实现的.微服务构建在不同的软件模块上,这些软件模块,有可能是由不同的团队开发.可能使用不同的编程语言来实现.有可能布在了几千台服务器,横跨多个不同的数据中心 ...

  6. 大规模分布式跟踪系统的理论

    概述 当代的互联网的服务,通常都是用复杂的.大规模分布式集群来实现的.互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发.可能使用不同的编程语言来实现.有可能布在了几千台服务器 ...

  7. Dapr牵手.NET学习笔记:可观测性-分布式跟踪

    分布式跟踪在dapr里是开箱即用的,不需要对应用作任何一丁点的侵入式编程.之前的开发,如果想实现分式跟踪,就得在应用中埋点,这是一个与业务无关系的动作.dpar通过sidecar可以轻松做到这点,从而 ...

  8. 在Spring Boot中实现相关ID(用于SOA /微服务中的分布式跟踪)

    上周参加了在Geecon上Sam Newman的微服务讨论后,我开始思考更多有关用于监视,报告和诊断的面向服务/微服务平台最可能的基本功能:相关ID. 关联ID允许在面向服务的复杂平台中进行分布式跟踪 ...

  9. 分布式 集群 系统组件架构_分布式跟踪系统的四个组件如何一起工作

    分布式 集群 系统组件架构 十年前,基本上只有认真思考分布式跟踪的人是学者和少数大型互联网公司. 如今,对于任何采用微服务的组织来说,它已经变成了赌注. 基本原理是公认的:微服务以令人惊讶且通常是惊人 ...

  10. 分布式监控apm_Datadog:APM和分布式跟踪的新Java支持

    分布式监控apm 作为Datadog应用程序性能监视的产品经理,我与客户紧密合作,以确保Datadog满足其代码级监视需求. 当我和我的团队考虑为Datadog的APM产品添加新的语言支持时,很明显J ...

最新文章

  1. Python-面向对象进阶
  2. 1.8 其他正则化方法-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  3. python 读取yml文件_Python 读取 yaml 配置文件 | 文艺数学君
  4. 信息学奥赛一本通 1026:空格分隔输出 | OpenJudge NOI 1.1 06
  5. TensorFlow 第一步 开门见山:Hello World!
  6. flask使用第三方云通讯平台时,出现{'172001':'网络错误'}解决方法
  7. linux安装typecho教程,Typecho上手指南
  8. POJ-2456.Aggressivecows.(二分求解最大化最小值)
  9. 随想录(中间件接口的定义方法)
  10. Unity3D GUI笔记
  11. Extjs的radio单选框的使用
  12. BSD协议和FreeBSD
  13. 小常识:软件常见的各种版本英文缩写
  14. Adjoint of SE(3)
  15. 水和水蒸气物性计算微信小程序
  16. 新年新气象,新的一年新的开始,给自己定个小小的目标,以此为证
  17. Dline,一款让你爱不释手的去中心化社交应用
  18. ABeam Recruiting | ABeam旗下艾宾信息技术开发(大连)2023届校招正式开启
  19. 数仓工具—Hive实战之拉链表(3)
  20. 视频压缩怎么弄?建议收藏这些方法

热门文章

  1. java自动化学习笔记
  2. 构建最基础的Spring项目及所需要的jar包
  3. HDU2072 tri树/map/set/字符串hash
  4. oracle之三 自动任务调度
  5. 小项目,吃货联盟,java初级小项目,源代码
  6. 博弈论:寻找先手必胜策略——Grundy值
  7. Oracle Data Guard的配置
  8. hdu 1005 根据递推公式构造矩阵 ( 矩阵快速幂)
  9. MSDN MTBETA
  10. PowerDesigner逆向工程,从SQL Server数据库生成Physical Model