携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
2. SkyWalking快速开始
2.1 SkyWalking Agent跟踪微服务
2.1.1 通过jar包方式接入
准备一个springboot程序,打成可执行jar包,写一个shell脚本,在启动项目的Shell脚本上,通过 -javaagent 参数进行配置SkyWalking Agent来跟踪微服务;
startup.sh脚本:
#!/bin/sh
# SkyWalking Agent配置
export SW_AGENT_NAME=springboot-skywalking-demo #Agent名字,一般使用`spring.application.name`
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置 Collector 地址。
export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为 300。
export JAVA_AGENT=-javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
java $JAVA_AGENT -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar #jar启动
启动日志
等同于
java -javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-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
# The service name in UI
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
# Backend service addresses.
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
我们也可以使用skywalking.+配置文件中的配置名作为系统配置项来进行覆盖。 javaagent参数配置方式优先级更高
-javaagent:D:\apache\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=springboot-skywalking-demo
-Dskywalking.collector.backend_service=192.168.3.100:11800
测试: http://192.168.3.100:8000/user/list
在启动程序前加一个-javaagent 参数即可完成对程序的跟踪
2.1.2 在IDEA中使用Skywalking
在运行的程序配置jvm参数,如下图所示:
# skywalking-agent.jar的本地磁盘的路径
-javaagent:D:\apache\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=springboot-skywalking-demo
# skywalking的collector服务的IP及端口
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.100:11800
2.1.3 Skywalking跨多个微服务跟踪
Skywalking跨多个微服务跟踪,只需要每个微服务启动时添加javaagent参数即可。
测试:
启动微服务mall-gateway,mall-order,mall-user ,配置skywalking的jvm参数
http://localhost:8888/user/findOrderByUserId/1
注意:此处存在bug,跟踪链路不显示gateway
拷贝agent/optional-plugins目录下的gateway插件到agent/plugins目录
2.2 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文件中的某一条规则就会触发告警。
比如service_resp_time_rule规则:
该规则表示服务{name}的响应时间在最近10分钟的3分钟内超过1000ms;
测试:
编写接口,模拟慢查询
@RequestMapping("/info/{id}")
public User info(@PathVariable("id") Integer id){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userService.getById(id);
}
回调接口
@RequestMapping("/notify")
public String notify(@RequestBody Object obj){
//TODO 告警信息,给技术负责人发短信,钉钉消息,邮件,微信通知等
System.err.println(obj.toString());
return "notify successfully";
}
在config/alarm-settings.yml中配置回调接口,并重启skywalking服务
测试访问:http://localhost:8000/user/info/1,满足告警规则后,控制台输出告警信息
SkyWalking UI显示告警信息
对接钉钉:
Webhook回调通知
SkyWalking告警Webhook回调要求接收方是一个Web容器(比如tomcat服务),告警的消息会通过HTTP请求进行发送, 请求方法为POST, Content-Type为application/json, JSON格式基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>的集合对象数据, 集合中的每个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
}]
2.3 Skywalking持久化跟踪数据
2.3.1 基于mysql持久化:
- 修改config目录下的application.yml,使用mysql作为持久化存储的仓库
- 修改mysql连接配置
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目录下
- 启动Skywalking
查看swtest数据库,可以看到生成了很多表。
说明启动成功了,打开配置对应的地址http://192.168.3.100:8080/,可以看到skywalking的web界面。
测试:重启skywalking,验证跟踪数据会不会丢失
2.3.2 基于elasticsearch持久化
1.准备好elasticsearch环境
启动elasticsearch服务
su - es
cd /usr/local/soft/elasticsearch-7.6.1/
bin/elasticsearch -d
)
启动elasticsearch-head服务,访问http://192.168.3.100:9100
cd /usr/local/soft/elasticsearch-head/node_modules/grunt
nohup bin/grunt server &
2.修改config/application.yml配置文件:
修改elasticsearch7的连接配置
- 启动Skywalking服务
启动时会向elasticsearch中创建大量的index索引用于持久化数据,每天会产生一个新的索引文件。
测试:
启动应用程序,查看跟踪数据是否已经持久化到elasticsearch的索引中,然后重启skywalking,验证跟踪数据会不会丢失
2.4 自定义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();
}
测试 http://localhost:8000/user/list
在Skywalking UI中查询tranceId
2.4.1 @Trace将方法加入追踪链路
如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可
测试:
2.4.2 加入@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);
}
2.5 Skywalking集成日志框架
引入依赖
<!-- 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 占位符
测试
Skywalking通过grpc上报日志 (需要v8.4.0)
gRPC报告程序可以将收集到的日志转发到SkyWalking OAP服务器上
logback-spring.xml中添加
<!-- v8.4.0提供 -->
<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"/>
<root level="info">
<appender-ref ref="grpc-log" />
</root>
打开agent/config/agent.config配置文件,添加如下配置信息:
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.3.100}
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在本地的可以不配
| 配置名 | 解释 | 默认值 |
|---|---|---|
| plugin.toolkit.log.transmit_formatted | 是否以格式化或未格式化的格式传输记录的数据 | true |
| plugin.toolkit.log.grpc.reporter.server_host | 指定要向其报告日志数据的grpc服务器的主机 | 127.0.0.1 |
| plugin.toolkit.log.grpc.reporter.server_port | 指定要向其报告日志数据的grpc服务器的端口 | 11800 |
| plugin.toolkit.log.grpc.reporter.max_message_size | 指定grpc客户端要报告的日志数据的最大大小 | 10485760 |
| plugin.toolkit.log.grpc.reporter.upstream_timeout | 客户端向上游发送数据时将超时多长时间。单位是秒 | 30 |
Skywalking UI效果
此处日期格式存在问题
2.6 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作为注册中心
修改nacos配置
可以选择性修改监听端口
修改存储策略,使用elasticsearch7作为storage
- 配置ui服务webapp.yml文件的listOfServers,写两个地址
- 启动服务测试
启动Skywalking服务,指定springboot应用的jvm参数
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.10:11800,192.168.3.12:11800