Skywalking

skywalking 是一个国产开源框架,是分布式系统的应用程序性能监视工具,专为微服务、云原生框架和基于容器(Docker、k8s、Mesos)架构而设计;Skywalking 是观察性分析平台和应用性能管理系统,提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案
官网:https://skywalking.apache.org
下载:https://skywalking.apache.org/downloads/
GIthub:https://github.com/apache/skywalking
社区文档:https://skyapm.github.io/document-cn-translation-of-skywalking/

调用链选型

  1. Zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单。
  2. Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能强大,接入端无代码侵入。
  3. SkyWalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。
  4. CAT是大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具

image.png

Skywalking 主要功能特性

  1. 多种监控手段,可以通过语言探针和service mesh获得监控的数据;
  2. 支持多种语言自动探针,包括 Java,.NET Core 和 Node.JS;
  3. 轻量高效,无需大数据平台和大量的服务器资源;
  4. 模块化,UI、存储、集群管理都有多种机制可选;
  5. 支持告警;
  6. 优秀的可视化解决方案

Skywalking 整体架构

image.png

整体架构分成四部分

  1. 上部分Agent :负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器;
  2. 下部分 SkyWalking OAP :负责接收Agent发送的Tracing数据信息,然后进行分析(Analysis Core),存储到外部存储器(Storage),最终提供查询(Query)功能;
  3. 右部分Storage:Tracing数据存储,目前支持ES、MySQL、Sharding Sphere、TiDB、H2多种存储器,目前采用较多的是ES,主要考虑是SkyWalking开发团队自己的生产环境采用ES为主;
  4. 左部分SkyWalking UI:负责提供控制台,查看链路等等

支持三种探针

  1. Agent – 基于ByteBuddy字节码增强技术实现,通过jvm的agent参数加载,并在程序启动时拦截指定的方法来收集数据。
  2. SDK – 程序中显式调用SkyWalking提供的SDK来收集数据,对应用有侵入。
  3. Service Mesh – 通过Service mesh的网络代理来收集数据

后端(Backend)

接受探针发送过来的数据,进行度量分析,调用链分析和存储。后端主要分为两部分:

  1. OAP(Observability Analysis Platform)- 进行度量分析和调用链分析的后端平台,并支持将数据存储到各种数据库中,如:ElasticSearch,MySQL,InfluxDB等。
  2. OAL(Observability Analysis Language)- 用来进行度量分析的DSL,类似于SQL,用于查询度量分析结果和警报

界面(UI)

  1. RocketBot UI – SkyWalking 7.0.0 的默认web UI
  2. CLI – 命令行界面

这三个模块的交互流程:
image.png

Skywalking 环境搭建部署

image.png

  • skywalking agent和业务系统绑定在一起,负责收集各种监控数据
  • Skywalking oapservice是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中;接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapservice通常以集群的形式存在
  • skywalking webapp,前端界面,用于展示数据
  • 用于存储监控数据的数据库,比如mysql、elasticsearch等

下载

https://skywalking.apache.org/downloads/
image.png
目录结构:
image.png

搭建 Skywalking OAP 服务

先使用默认的 H2 数据库存储,不用修改配置

config/application.yml
image.png
启动脚本 bin/startup.sh
image.png
日志信息存储在 logs 目录
image.png
启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui
skywalking-oap-server 服务启动后会暴露11800 和 12800 两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/applicaiton.yml
image.png
skywalking-web-ui服务会占用 8080 端口, 修改端口可以修改webapp/webapp.yml
image.png
server.port:SkyWalking UI服务端口,默认是8080;
collector.ribbon.listOfServers:SkyWalking OAP服务地址数组,SkyWalking UI界面的数据是通过请求SkyWalking OAP服务来获得
image.png

Skywalking 概念

  1. 服务(Service) :表示对请求提供相同行为的一系列或一组工作负载,在使用Agent时,可以定义服务的名字
  2. 服务实例(Service Instance) :上述的一组工作负载中的每一个工作负载称为一个实例, 一个服务实例实际就是操作系统上的一个真实进程
  3. 端点(Endpoint) :对于特定服务所接收的请求路径, 如HTTP的URI路径和gRPC服务的类名 + 方法签名

Skywalking 快速开始

Skywalking Agent 跟踪微服务

通过 jar 包方式接入

准备一个springboot程序,打成可执行jar包,写一个shell脚本,在启动项目的Shell脚本上,通过 -javaagent 参数进行配置SkyWalking Agent来跟踪微服务

startup.sh脚本:

  1. #!/bin/sh
  2. # SkyWalking Agent配置
  3. export SW_AGENT_NAME=springboot-skywalking-demo #Agent名字,一般使用`spring.application.name`
  4. export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置 Collector 地址。
  5. export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为 300
  6. export JAVA_AGENT=-javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
  7. java $JAVA_AGENT -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar #jar启动

image.png
等同于:

  1. java -javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
  2. -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
  3. -DSW_AGENT_NAME=springboot-skywalking-demo -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar

参数名对应 agent/config/agent.config 配置文件中的属性;
属性对应的源码:org.apache.skywalking.apm.agent.core.conf.Config.java

  1. # The service name in UI
  2. agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
  3. # Backend service addresses.
  4. collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}

可使用skywalking.+配置文件中的配置名作为系统配置项来进行覆盖;javaagent参数配置方式优先级更高

  1. -javaagent:D:\apache\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
  2. -Dskywalking.agent.service_name=springboot-skywalking-demo
  3. -Dskywalking.collector.backend_service=192.168.3.100:11800

测试:在启动程序前加一个-javaagent 参数即可完成对程序的跟踪
image.png

在 idea 中使用 Skywalking

在运行的程序配置 jvm 参数:
image.png

  1. # skywalking-agent.jar的本地磁盘的路径
  2. -javaagent:D:\apache\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
  3. # skywalking上显示的服务名
  4. -DSW_AGENT_NAME=springboot-skywalking-demo
  5. # skywalkingcollector服务的IP及端口
  6. -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.100:11800

Skywalking 跨多个微服务跟踪

只需要每个微服务启动时添加 javaagent 参数即可
image.png

注:此处存在 bug,跟踪链路不显示 gateway

拷贝agent/optional-plugins目录下的gateway插件到agent/plugins目录
image.png

Skywalking 告警通知

skywalking告警的核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中,告警规则的定义分为三部分:

  1. 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件
  2. 网络钩子(Webhook}:当警告触发时,哪些服务终端需要被通知
  3. gRPC钩子:远程gRPC方法的主机和端口,告警触发后调用;

为了方便,skywalking发行版中提供了默认的alarm-setting.yml文件,包括一些规则,每个规则有英文注释,可以根据注释得知每个规则的作用:

  • 在最近10分钟的3分钟内服务平均响应时间超过1000ms
  • 最近10分钟内,服务成功率在2分钟内低于80%
  • 服务实例的响应时间在过去10分钟的2分钟内超过1000ms
  • 数据库访问{name}的响应时间在过去10分钟的2分钟内超过1000ms

只要我们的服务请求符合alarm-setting.yml文件中的某一条规则就会触发告警。
es:service_resp_time_rule规则
image.png
该规则表示服务{name}的响应时间在最近10分钟的3分钟内超过1000ms;

测试:编写接口,模拟慢查询

  1. @RequestMapping("/info/{id}")
  2. public User info(@PathVariable("id") Integer id){
  3. try {
  4. Thread.sleep(2000);
  5. } catch (InterruptedException e) {
  6. e.printStackTrace();
  7. }
  8. return userService.getById(id);
  9. }

回调接口:

@RequestMapping("/notify")
public String notify(@RequestBody Object obj){
    //TODO 告警信息,给技术负责人发短信,钉钉消息,邮件,微信通知等
    System.err.println(obj.toString());
    return "notify successfully";
}

在config/alarm-settings.yml中配置回调接口,并重启skywalking服务
image.png
测试访问:http://localhost:8000/user/info/1,满足告警规则后,控制台输出告警信息
image.png
SkyWalking UI显示告警信息
image.png

对接钉钉:
image.png

Webhook 回调通知

SkyWalking告警Webhook回调要求接收方是一个Web容器(比如tomcat服务),告警的消息会通过HTTP请求进行发送, 请求方法为POST, Content-Type为application/json, JSON格式基于ListAlarmMessage>的集合对象数据, 集合中的每个AlarmMessage包含以下信息:

  1. scopeId. 所有可用的Scope,参考org.apache.skywalking.oap.server.core.source.DefaultScopeDefine
  2. name. 目标 Scope 的实体名称
  3. id0. Scope 实体的 ID
  4. id1. 未使用
  5. ruleName. 在 alarm-settings.yml 中配置的规则名
  6. alarmMessage. 报警消息内容
  7. startTime. 告警时间, 位于当前时间与 UTC 1970/1/1 之间
    [{
     scopeId = 2,
     scope = SERVICE_INSTANCE,
     name = 98e1839 a6fdf48b0aedb0ecabb8ea5f7 @192 .168 .233 .1 of springboot - skywalking - demo,
     id0 = c3ByaW5nYm9vdC1za3l3YWxraW5nLWRlbW8 = .1 _OThlMTgzOWE2ZmRmNDhiMGFlZGIwZWNhYmI4ZWE1ZjdAMTkyLjE2OC4yMzMuMQ == ,
     id1 = ,
     ruleName = service_instance_resp_time_rule,
     alarmMessage = Response time of service instance 98e1839 a6fdf48b0aedb0ecabb8ea5f7 @192 .168 .233 .1 of springboot - skywalking - demo is more than 1000 ms in 2 minutes of last 10 minutes,
     startTime = 1613913565462
    }, {
     scopeId = 6,
     scope = ENDPOINT_RELATION,
     name = User in User to / user / info / {
         id
     } in springboot - skywalking - demo,
     id0 = VXNlcg == .0 _VXNlcg == ,
     id1 = c3ByaW5nYm9vdC1za3l3YWxraW5nLWRlbW8 = .1 _L3VzZXIvaW5mby97aWR9,
     ruleName = endpoint_relation_resp_time_rule,
     alarmMessage = Response time of endpoint relation User in User to / user / info / {
         id
     } in springboot - skywalking - demo is more than 1000 ms in 2 minutes of last 10 minutes,
     startTime = 1613913565462
    }]
    

Skywalking 持久化跟踪数据

基于 Mysql 持久化

修改config目录下的application.yml,使用mysql作为持久化存储的仓库
image.png
修改mysql连接配置
image.png

storage:
  #选择使用mysql   默认使用h2,不会持久化,重启skyWalking之前的数据会丢失
  selector: ${SW_STORAGE:mysql}
  #使用mysql作为持久化存储的仓库
  mysql:
    properties:
      #数据库连接地址
      jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://1ocalhost:3306/swtest"}
      #用户名
      dataSource.user: ${SW_DATA_SOURCE_USER:root}
      #密码
      dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}

注:需要添加mysql数据驱动包,因为在lib目录下是没有mysql数据驱动包的,所以修改完配置启动是会报错,启动失败

添加mysql数据驱动包到oap-libs目录下
image.png
启动Skywalking
image.png
查看swtest数据库,可以看到生成了很多表
image.png
说明启动成功了,打开配置对应的地址,可以看到skywalking的web界面

基于 elasticsearch 持久化

准备好elasticsearch环境,启动elasticsearch服务

su - es
cd /usr/local/soft/elasticsearch-7.6.1/
bin/elasticsearch -d

启动elasticsearch-head服务

cd /usr/local/soft/elasticsearch-head/node_modules/grunt
nohup bin/grunt server &

image.png
修改config/application.yml配置文件:
image.png
修改elasticsearch7的连接配置
image.png
启动Skywalking服务
image.png
启动时会向elasticsearch中创建大量的index索引用于持久化数据,每天会产生一个新的索引文件。
测试:
启动应用程序,查看跟踪数据是否已经持久化到elasticsearch的索引中,然后重启skywalking,验证跟踪数据会不会丢失
image.png

自定义 Skywalking 链路追踪

引入依赖:

<!-- SkyWalking 工具类 -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.4.0</version>
</dependency>

在业务方法中可以 TraceContext 获取到 traceId

@RequestMapping("/list")
public List<User> list(){

    //TraceContext可以绑定key-value
    TraceContext.putCorrelation("name", "fox");
    Optional<String> op = TraceContext.getCorrelation("name");
    log.info("name = {} ", op.get());
    //获取跟踪的traceId
    String traceId = TraceContext.traceId();
    log.info("traceId = {} ", traceId);

    return userService.list();
}

测试:
image.png
在Skywalking UI中查询tranceId
image.png

@Trace 将方法加入追踪链路

image.png
测试
image.png

@Tags 或@Tag

还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。实现方式:在方法上增加@Tag或者@Tags

@Trace
@Tag(key = "list", value = "returnedObj")
public List<User> list(){
    return userMapper.list();
}

@Trace
@Tags({@Tag(key = "param", value = "arg[0]"),
        @Tag(key = "user", value = "returnedObj")})
public User getById(Integer id){
    return userMapper.getById(id);
}

image.png
image.png

Skywalking 集成日志框架

log4j 官方配置:https://skywalking.apache.org/docs/main/v8.4.0/en/setup/service-agent/java-agent/application-toolkit-log4j-1.x/
log4j2j 官方配置:https://skywalking.apache.org/docs/main/v8.4.0/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x/

引入依赖:

<!-- apm-toolkit-logback-1.x -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.4.0</version>
</dependency>

添加logback-spring.xml文件,并配置 %tid 占位符
logback-spring.xml
image.png

Skywalking 集群部署

Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行跟踪

搭建一个skywalking oap集群需要:

  1. 至少一个Nacos(也可以是nacos集群)
  2. 至少一个ElasticSearch(也可以是es集群)
  3. 至少2个skywalking oap服务
  4. 至少1个UI(UI也可以集群多个,用Nginx代理统一入口)

修改config/application.yml文件,使用nacos作为注册中心:
image.png
修改 nacos 配置
image.png
选择性修改监听端口
image.png
修改存储策略,使用 es 作为 storage
image.png
image.png
配置 UI 服务 webapp.yml 文件的 listOfServers,添加地址
image.png
启动服务测试,指定springboot 应用的 jvm 参数

-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.10:11800,192.168.3.12:11800