微服务链路追踪SkyWalking
1、简介
skywalking是分布式系统的应用
程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。它是一款优秀的
APM(Application Performance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。
官网:http://skywalking.apache.org/
下载:http://skywalking.apache.org/downloads/
Github:https://github.com/apache/skywalking
文档:https://skywalking.apache.org/docs/main/v8.4.0/readme/
中文文档:https://skyapm.github.io/document-cn-translation-of-skywalking/
架构图:
① skywalking agent和业务系统绑定在一起,负责收集各种监控数据
② Skywalking oapservice是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中; 接受skywalkingwebapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapservice通常以集 群的形式存在。
③ skywalking webapp,前端界面,用于展示数据。
④ 用于存储监控数据的数据库,比如mysql、elasticsearch等
2、下载安装
2.1 下载地址 https://skywalking.apache.org/downloads/
选择对应版本的Distribution 我连es7版本所以选择 v8.6.0 for H2/MySQL/TiDB/InfluxDB/ElasticSearch 7
2.2 目录介绍
① webapp : UI前端的jar包和配置文件
② oap-libs:后台应用的jar包,以及依赖jar包,
③ config:启动后台应用程序的配置文件
④ bin 各种启动脚本,一般使用startup.*来启动。它是组合脚本,会同时启动oapService.和webappService.
⑤agent
skywalking-agent.jar 代理服务jar
config 代理服务启动时使用的配置文件
plugins 包含多个插件,代理服务启动时会加载该目录下的所有插件(jar包)
optional-plugins 可选插件,当需要支持某种功能时,如gateway,mysql等就需要手动拷贝jar
2.3 修改存储方式
进入/home/soft/skywalking/apache-skywalking-apm-bin-es7/config下的application.yml
修改这句(我用es作存储的,具体根据自己需求可选mysql、h2等) storage: selector:
${SW_STORAGE:elasticsearch7} 记得在elasticsearch7里面配置连接es的url和账号密码
storage:
selector: ${SW_STORAGE:elasticsearch7}
这里配置连接es的地址与账号密码,没有就配置""
elasticsearch7:
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
user: ${SW_ES_USER:""}
password: ${SW_ES_PASSWORD:""}
注意: ①如果使用的是mysql,需要手动把本地mysql驱动包(即:mysql-connector-java-8.0.19.jar)拷贝到oap-libs目录下
② 如果有gateway的链路追踪,拷贝agent/optional-plugins目录下的gateway(即:apm-spring-cloud-gateway-2.1.x-plugin-8.7.0.jar)插件到agent/plugins目录
其他不用变
2.4 修改UI端的端口(防止冲突)
进入/home/soft/skywalking/apache-skywalking-apm-bin-es7/webapp
vim webapp.yml
修改(自己改为不易冲突端口即可)
server
port: 10081
2.5 修改服务名
进入:/home/soft/skywalking/apache-skywalking-apm-bin-es7/agent/config
vim agent.config 修改
agent.service_name=${SW_AGENT_NAME:skywalking_tomcat}
2.6 启动
进入/home/soft/skywalking/apache-skywalking-apm-bin-es7/bin
执行:sh startup.sh
日志存放目录:/home/soft/skywalking/apache-skywalking-apm-bin-es7/logs
可查看启动有没错 现在即可登录浏览器查看skywalking是否启动http://192.168.200.141:10081/
(记得开放服务器的对应端口我的是10081)
3 启动项目
服务器linux 启动springboot项目(虚拟机启动方式)
编辑启动配置:(示例)
nohup java -Xms512m -Xmx2048m -XX:PermSize=1024M -XX:MaxNewSize=108m -XX:MaxPermSize=2048m
# skywalking‐agent.jar的本地磁盘的路径
-javaagent:/mydata/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=auth
# skywalking的collector服务的IP及端口
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.183.129:11800
-jar auth.jar &
docker启动:(修改dockerfile 示例)
FROM adoptopenjdk/openjdk8 VOLUME /tmp COPY
localtime /etc/localtime RUN echo "Asia/Shanghai" > /etc/timezone COPY
target/spring-demo-*.jar app.jar COPY agent /usr/local/agent
ENTRYPOINT [ "sh", "-c", "java
-javaagent:/usr/local/agent/skywalking-agent.jar
-Dskywalking.agent.service_name=spring-demo
-Dskywalking.collector.backend_service=192.168.1.2:11800 -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
至此可以在skywalking的页面看到服务间的调用,链路追踪等信息。Skywalking跨多个微服务跟踪,只需要每个微服务启动时添加javaagent参数即可。
注意: 跟踪链路不显示gateway.拷贝
agent/optional-plugins目录下的gateway插件到agent/plugins目录。连接mysql也要拷对应的驱动包进去。添加mysql数据驱动包到oap-libs目录下
4、自定义SkyWalking链路追踪
自定义追踪即是在每个(或者想要的)请求上加上请求参数和返回参数的获取
4.1、导入包
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.6.0</version>
</dependency>
4.2、在业务方法上加上注解@Trace将方法加入追踪链路
注意:
① 这里是加在业务层,即@Service层,不要加在@Controller,没有用的。如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可。
② 加入@Tags或@Tag 我们还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。实现方式:在方法上增加@Tag或者@Tags。 @Tag 注解中 key = 方法名 ; value =returnedObj返回值 arg[0] 参数
这里注意returnedObj是固定写法,里面还有个ed,之前一直没追踪到数据就是写错了

4.3 skywalking返回信息查看

5、性能分析
6、Skywalking集成日志框架
以logback日志框架为例
6.1 导包
注意版本跟自己的skywalking相适配
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.6.0</version>
</dependency>
6.2 在项目resource下下一个xml文件
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
</layout>
</encoder>
</appender>
<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="grpc-log"/>
</root>
</configuration>
如果skywalking不是部署在本地需要配置
apache-skywalking-apm-es7-8.6.0\apache-skywalking-apm-bin-es7\agent\config\agent.config#加入skywalking没有部署在本地 需要配置地址(地址跟自己部署的服务器一致)
打开agent/config/agent.config配置文件,添加如下配置信息:plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1} plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800} plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760} plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}
以上配置是默认配置信息,agent与oap在本地的可以不配
7、SkyWalking 告警功能
在config/alarm-settings.yml文件中
7.1、 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。
SkyWalking 的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下:
- 过去 3 分钟内服务平均响应时间超过 1 秒。
- 过去 2 分钟服务成功率低于80%。
- 过去 3 分钟内服务响应时间超过 1s 的百分比
- 服务实例在过去 2 分钟内平均响应时间超过 1s,并且实例名称与正则表达式匹配。
- 过去 2 分钟内端点平均响应时间超过 1 秒。
- 过去 2 分钟内数据库访问平均响应时间超过 1 秒。
- 过去 2 分钟内端点关系平均响应时间超过 1 秒。
这些预定义的告警规则,打开config/alarm-settings.yml文件即可看到告警规则配置项的说明:
1.Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
2. Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script
3.Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
4.Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空)
5.Threshold:阈值
6. OP: 操作符,目前支持 >、<、=
7. Period:多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配
8.Count:在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报
9.Silence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着
相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次
10.message:告警消息
7.2、 Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知
Webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是
Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件。当该
事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。 SkyWalking的告警消息会通过
HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,其JSON 数据实基于
List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage进行序列化的
webhooks:
- http://127.0.0.1/notify/
- http://127.0.0.1/go-wechat/
SkyWalking是不支持直接向邮箱、短信等服务发送告警信息的,SkyWalking只会在发生告警时将
告警信息发送至配置好的Webhook接口。
但我们总不能人工盯着该接口的日志信息来得知服务是否发生了告警,因此我们需要在该接口里实现发送邮件或短信等功能,从而达到个 性化的告警通知