1. 故事背景

在微服务里,少不了分布式跟踪(全链路跟踪)。当服务发现问题时,可以快速定位问题故障点在哪?当服务性能差的时候,可以知道性能差在哪个服务?

2. 提前准备

  • 本次试验是在CentOS 7.4 64位系统,root用户下进行
  • Kubernetes(k8s)集群
  • istio版本1.0.2

3. 实践

参考官网文档:分布式跟踪

Istio集成了Jaeger(实际上更多,我没有深入了解),在使用上很方便,比单独使用Jaeger要容易很多。Tracing在Istio是属于可选项,默认不会安装,在Istio - 安装及注意事项中有提到,按照这种方式安装成功,这个功能就可以使用了。但你还需要做两件事情:

1.让我们可以访问到Jaeger的Dashboard。其中官网使用的端口转发的方式,而我的集群在服务器上,这种方式不是特别方便,所以我使用Ingress,配置文件如下:

给予Jaeger Dashboard一个域名,然后把这个请求转发到他的Service上

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: bar
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.frontend.passHostHeader: "true"
spec:
  rules:
  - host: 'jaeger.foo.bar.com'
    http:
      paths:
      - path: /
        backend:
          serviceName: jaeger-query 
          servicePort: 16686

2.虽然Istio代理能够自动发送Tracing所需的相关信息,但对于微服务应用内部是侵入不到的。

Tracing是整个Istio唯一一处对应用有侵入的功能(其实是不是我也不知道,我目前了解到的是) 其实侵入性也很低(个人感觉),可以不用在意,因为可以统一处理,不影响业务代码

为了达到Tracing的效果,应用应该从请求源头中收集下列的 HTTP Header,并传播给外发请求:

  • x-request-id
  • x-b3-traceid
  • x-b3-spanid
  • x-b3-parentspanid
  • x-b3-sampled
  • x-b3-flags
  • x-ot-span-context

那该怎么加呢?按照官网的方式会死人的,对代码浸入极高,一开始我排斥就是因为他的例子。 我使用了简单的办法,主要是两步:

  1. 在Web层使用了拦截器/过滤器,在此处把上游的Tracing信息收集起来。
  2. 在服务内部调用其他服务时,把刚刚收集的信息,放置于其Header,让其传播下去。

通过这种方式,对代码侵入性很低,无论用还是不用,都不影响业务。

4. 总结

我现在已经在生产环境上,使用了这个功能,的的确确帮助很大,发挥了其应有的功能。让我一个运维小白,轻轻松松拥有。 不过我在JAVA上使用这个功能,也碰到一些坎,这个后面单独说。