乐趣区

关于java:别说不会微服务了六分钟教你巧妙玩转分布式下链路追踪

本篇文章我将给大家介绍“分布式链路追踪”的内容,对于目前大部分采纳微服务架构的公司来说,分布式链路追踪都是必备的,无论它是传统微服务体系亦或是新一代 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 ns
NAME                   STATUS   AGE
default                Active   10d
kube-node-lease        Active   10d
kube-public            Active   10d
kube-system            Active   10d
kubernetes-dashboard   Active   10d
skywalking             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/v1
kind: Deployment
metadata:
  name: oap
  namespace: skywalking
spec:
  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: v1
kind: Service
metadata:
  name: oap
  namespace: skywalking
  labels:
    service: oap
spec:
  ports:
    #restful 端口
    - port: 12800
name: rest
     #rpc 端口
    - port: 11800
      name: grpc
    - port: 1234
      name: page
  selector:
    app: oap

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui-deployment
  namespace: skywalking
  labels:
    app: ui
spec:
  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: v1
kind: Service
metadata:
  name: ui
  namespace: skywalking
  labels:
    service: ui
spec:
  ports:
    - port: 8080
      name: page
      nodePort: 31234
  type: NodePort
  selector:
    app: ui

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

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

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

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

# 查看 skywalking 空间中的 Pod、Service 对象的运行状况
$ kubectl get all -n skywalking
NAME                                 READY   STATUS    RESTARTS   AGE
pod/oap-5f6d6bc4f6-k4mvv             1/1     Running   0          36h
pod/ui-deployment-868c66449d-fffrt   1/1     Running   0          36h

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                        AGE
service/oap   ClusterIP   10.110.112.244   <none>        12800/TCP,11800/TCP,1234/TCP   36h
service/ui    NodePort    10.100.154.93    <none>        8080:31234/TCP                 36h

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/oap             1/1     1            1           36h
deployment.apps/ui-deployment   1/1     1            1           36h

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/oap-5f6d6bc4f6             1         1         1       36h
replicaset.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 集群向外裸露的节点入口 IP
http://10.211.55.12:31234/ 

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

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

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

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

后记

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

写在最初

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

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

退出移动版