本篇文章我将给大家介绍“分布式链路追踪”的内容,对于目前大部分采纳微服务架构的公司来说,分布式链路追踪都是必备的,无论它是传统微服务体系亦或是新一代Service Mesh的微服务架构!而具体介绍的内容,本文不是齐全讲实践,而是心愿从实践到实际,疏导大家去操作,因为只有这样能力真正从技术层面有粗浅的意识和理解!

分布式链路追踪概述

在具体介绍分布式链路追踪零碎之前,咱们首先须要了解下什么是链路追踪?在本专栏后面对于监控零碎的介绍中能够晓得,监控零碎的观测数据次要来源于统计指标、日志以及链路追踪这三个方面。而这些数据从类型上又能够划分为两种:申请级别、聚合级别

申请级别的数据次要来源于实在的申请,例如一次HTTP调用、RPC调用等,本文要介绍的链路追踪就是这种类型。而聚合级别则是接口申请的度量指标或者一些参数数据的聚合,如QPS、CPU使用率等数值。日志和统计指标数据既能够是申请级别,也能够是聚合级别,因为它们可能来自源于实在的申请,也可能是零碎本身诊断时记录下来的信息。

对于链路追踪来说,它次要的逻辑就是将申请链路的残缺行为记录下来,以便能够通过可视化的模式实现链路查问、性能剖析、依赖关系、拓扑图等分布式链路追踪相干的性能。如下图所示:

在上图中假如微服务零碎中的一次接口调用总共有两个微服务参加,其调用关系别离是A->B->C,其中B服务还与Redis这样的第三方服务产生了调用关系、C服务则还须要调用MySQL数据库服务。所以实际上链路追踪所做的事件就是具体记录A->B(B->Redis)->C(C->MySQL)这条残缺链路上的具体调用信息,例如接口响应后果、耗时等。

那么这条调用链路上的数据到底是怎么被记录的呢?接下来咱们持续以下面的调用链为例剖析下链路追踪信息的具体组成和传递模式,以便进一步了解分布式链路追踪零碎的原理和概念。具体逻辑示意图如下:

如上图所示,分布式链路追踪所监控的对象就是一次次调用所产生的链路,图中1-8所示的就是一条残缺的链路(Trace),零碎会通过惟一的标识(TraceId)对此进行记录。而链路中的每一个依赖调用都会生成一个调用形迹信息(Span),最开始生成的Span叫做根Span(Root Span),后续生成的Span都会将前一个Span 的标示(Sid)作为本Span信息的父ID(Pid)。

这样以此类推,Span信息就会随着链路的执行被过程内或跨过程进行上下文传递,通过Span数据链就能将一次次链路调用所产生的形迹信息串联起来,而每一个Span之上附着的日志信息(Annotation)就是咱们进行调用链监控剖析的数据起源。这就是分布式链路追踪的基本原理

而说到这里,你可能会有疑难:监控这么大的数据量,是不是会很耗费系统资源?的确如此,所以大部分链路追踪零碎,都会存在一个叫做采样率(Sampling)的设定,用来控制系统采集链路信息的比例,从而晋升零碎性能。因为很多时候,大量的链路信息都是雷同的,咱们须要关注的可能也只是绝对耗时较高、出错次数较多的链路,而并没有必要100%的进行采集。

SkyWalking简介

后面咱们从基本原理的角度阐明了链路追踪是什么,那么接下来咱们将介绍下目前最风行的分布式链路追踪零碎——SkyWalking。

SkyWalking是一款优良的开源APM(Application Performance Management)零碎,它不仅提供了链路追踪,链路剖析等分布式追踪性能,还反对性能指标剖析、利用和服务依赖性剖析、服务拓扑图剖析、报警等一系列利用性能监控相干的性能,能够帮忙咱们无效地定位问题。

而从数据收集上看,SkyWalking反对多种不同的数据起源及格局,包含反对Java、.NET Core、NodeJS、PHP和Python等不同语言的无侵入式Agent探针,以及对Service Mesh(服务网格)架构的反对等。其具体构造如下图所示:

如上图所示,SkyWalking的外围由链路收集服务器(Receiver Cluster)、聚合服务器(AggregatorCluster)组成。其中Receiver Cluster是整个后端服务接入的入口,专门用于收集服务的各种指标及链路信息。

而AggregatorCluster则用于汇总、聚合收集器收集到的数据,并最终将聚合数据存储到数据库中,而具体存储形式能够有多种,例如常见的ElasticSearch、MySQL、TIDB等,咱们能够依据理论须要进行抉择。这些聚合数据前面能够用于告警设置,也能够被GUI/CLI等可视化零碎以HTTP的模式拜访后进行可视化展现。

此外,从数据采集逻辑上看,SkyWalking反对多种语言探针及我的项目协定,可能笼罩目前大部分支流的分布式技术栈,具体来说次要有以下3种:

  • Metrics System:统计零碎。反对间接从Prometheus中拉取度量指标数据到SkyWalking,也反对程序本身通过micrometer推送数据;
  • Agents:业务探针。指在各个业务零碎中集成探针服务来进行链路追踪,即链路数据采集。SkyWalking反对Java、Go、.NET、PHP、NodeJS、Python、Nginx LUA等多种语言的探针。此外,它还反对通过gRPC或者HTTP的形式来传递数据;
  • Service Mesh:SkyWalking还反对对新一代微服务架构Service Mesh的监控,能够通过特定的Service Mesh协定采集数据面、管制面的数据,实现对服务网格链路数据的观测;

下面的内容简略介绍了SkyWalking的根本状况,并就其零碎架构进行了简略剖析。实际上SkyWalking最近两年倒退得十分快,社区也十分沉闷,在微服务链路追踪、利用性能监控畛域被应用得也越来越宽泛,因为篇幅起因,这里无奈进行更深刻的分享,感兴趣的读者能够通过官网文档或社区进行深刻理解!

SkyWalking装置部署

后面的内容别离介绍了分布式链路追踪的基本原理,并着重介绍了SkyWalking!很显然,写到这里就完结的话,本文就没有啥价值了,因为只是说了一堆正确的废话,看了也就忘了!这显然也不合乎我分享的格调,接下来咱们就从试验的角度来玩一下SkyWalking。

以下内容须要进行理论试验操作,如果在地铁上不不便能够先珍藏,有工夫再具体试验玩下!

对于SkyWalking的部署次要波及到后端OAP Server和前端UI,依据理论须要能够将它们部署在物理机虚拟机或者Kubernetes集群之中。这里为了演示环境的一致性,咱们抉择将SkyWalking的后端服务及UI别离部署到Kubernetes集群中。

而具体装置SkyWalking的形式能够通过官网提供的Kubernetes部署文件采纳Helm形式装置,也能够手动编写Kubernetes部署文件,这里为了便于学习,咱们采纳后一种形式。具体步骤如下:

1)、在Kubernetes集群中创立一个独自运行SkyWalking容器的Namespace。命令如下:

#通过kubectl连贯Kubernetes集群后执行,创立namespace命令$ kubectl create ns skywalking

命令执行实现后,能够查看Namespace是否创立胜利,命令如下:

#查看namespace创立状况$ kubectl get nsNAME                   STATUS   AGEdefault                Active   10dkube-node-lease        Active   10dkube-public            Active   10dkube-system            Active   10dkubernetes-dashboard   Active   10dskywalking             Active   46s

能够看到此时skywalking空间曾经胜利创立!

2)、编写SkyWalking-UI及OAP Server服务Kubernetes部署文件

在编写具体的Kubernetes部署文件的过程中须要指定SkyWalking-UI及OAP Server的容器镜像,一般来说能够通过源码手动打包也能够间接应用官网曾经打包好的镜像。这里为了不便演示,采纳Docker官网镜像仓库中曾经打包好的镜像。具体如图所示:

如果下面两张图所示,咱们别离在Docker Hub官网镜像仓库中找到了SkyWalking-UI及OAP Server的官网公布的容器镜像版本,接下来编写具体的部署文件。

编写SkyWalking服务端Kubernetes部署文件(skywalking-aop.yml),具体内容如下:

apiVersion: apps/v1kind: Deploymentmetadata:  name: oap  namespace: skywalkingspec:  replicas: 1  selector:    matchLabels:      app: oap      release: skywalking  template:    metadata:      labels:        app: oap        release: skywalking    spec:      containers:        - name: oap          #指定OAP Server容器镜像及版本信息          image: apache/skywalking-oap-server:8.3.0-es7          imagePullPolicy: IfNotPresent          ports:            - containerPort: 11800              name: grpc            - containerPort: 12800              name: rest---apiVersion: v1kind: Servicemetadata:  name: oap  namespace: skywalking  labels:    service: oapspec:  ports:    #restful端口    - port: 12800name: rest     #rpc端口    - port: 11800      name: grpc    - port: 1234      name: page  selector:    app: oap

以上是一个规范的Kubernetes部署文件,对于文件中相干指令的具体含意可查阅Kubernetes相干的材料。

编写SkyWalking-UI部署文件(skywalking-ui.yml),具体内容如下:

apiVersion: apps/v1kind: Deploymentmetadata:  name: ui-deployment  namespace: skywalking  labels:    app: uispec:  replicas: 1  selector:    matchLabels:      app: ui  template:    metadata:      labels:        app: ui    spec:      containers:        - name: ui          image: apache/skywalking-ui:8.3.0          ports:            - containerPort: 8080              name: page          env:            - name: SW_OAP_ADDRESS              value: oap:12800---apiVersion: v1kind: Servicemetadata:  name: ui  namespace: skywalking  labels:    service: uispec:  ports:    - port: 8080      name: page      nodePort: 31234  type: NodePort  selector:    app: ui

3)、依据编写的部署文件,执行Kubernetes部署命令

依据后面步骤中编写的Kubernetes公布文件,这里咱们依据编写的公布文件间接执行部署命令,具体如下:

#进入公布文件的存储目录,间接一次性执行全副文件部署命令$ kubectl apply -f .deployment.apps/oap createdservice/oap createddeployment.apps/ui-deployment createdservice/ui created

执行实现后通过命令查看具体部署的状况,命令如下:

#查看skywalking空间中的Pod、Service对象的运行状况$ kubectl get all -n skywalkingNAME                                 READY   STATUS    RESTARTS   AGEpod/oap-5f6d6bc4f6-k4mvv             1/1     Running   0          36hpod/ui-deployment-868c66449d-fffrt   1/1     Running   0          36hNAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                        AGEservice/oap   ClusterIP   10.110.112.244   <none>        12800/TCP,11800/TCP,1234/TCP   36hservice/ui    NodePort    10.100.154.93    <none>        8080:31234/TCP                 36hNAME                            READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/oap             1/1     1            1           36hdeployment.apps/ui-deployment   1/1     1            1           36hNAME                                       DESIRED   CURRENT   READY   AGEreplicaset.apps/oap-5f6d6bc4f6             1         1         1       36hreplicaset.apps/ui-deployment-868c66449d   1         1         1       36h

能够看到部署的SkyWalking服务都曾经失常运行!如果是第一次部署,拉取镜像的过程可能会比较慢一点。如果在部署过程中存在问题,也能够查看Pod对象的运行日志,例如:

#能够查看aop的启动日志$ kubectl logs pod/oap-5f6d6bc4f6-k4mvv -n skywalking

4)、查看SkyWalking-UI的Web拜访地址

通过上述步骤,咱们曾经胜利将SkyWalking-UI、OAP Server两个服务运行在Kubernetes集群之中。接下来通过SkyWalking-UI服务的映射端口(k8s部署文件中定义是31234端口)拜访Web UI,具体可通过http://NodeIP:31234进行拜访,例如:

#这里的IP为Kubernetes集群向外裸露的节点入口IPhttp://10.211.55.12:31234/ 

如果不晓得Kubernetes集群节点入口IP地址,能够通过以下命令进行查看:

#查问SkyWalking-UI所部署的Kubernetes集群Node节点的IP地址$ kubectl describe node kubernetesName:               kubernetesRoles:              master...Addresses:  InternalIP:  10.211.55.12  Hostname:    kubernetes...

拜访后的界面显示成果如下图所示:

如上图所示,此时能够看到SkyWalking已胜利运行,因为尚无服务接入所以临时还看不到有任何监控数据!

后记

如后面所述内容咱们曾经在Kubernetes环境中将分布式链路追踪零碎部署胜利了,另外因为还没有服务接入所以临时还看不到任何链路追踪数据,然而因为篇幅的起因这里就不持续介绍如何将Java微服务接入SkyWalking了,然而这个这个接入过程却是十分有意思的,因为它是咱们作为研发人员,进一步了解微服务程序与分布式链路追踪系统集成、交互的要害!这部分我将作为续集在下一篇文章中给大家分享,工夫不会太久,期待大家放弃关注!

写在最初

欢送大家关注我的公众号【惊涛骇浪如码】,海量Java相干文章,学习材料都会在外面更新,整顿的材料也会放在外面。

感觉写的还不错的就点个赞,加个关注呗!点关注,不迷路,继续更新!!!