目录
SkyWalking通过grpc上报日志(需要v.8.4.0+)
一、前言
对于一个大型的几十个、几百个微服务构成的微服务架构系统,通常会遇到一些问题,比如:
1.如何串联整个调用链路,快速定位问题?
2.如何缕清各个微服务之间的依赖关系?
3.如何进行各个微服务接口的性能分析?
4.如何跟踪整个业务流程的调用处理顺序?
二、SkyWalking是什么
SkyWalking是一个国产开源框架。SkyWalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s)架构而设计。它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪、性能分析、应用和服务依赖分析等。
下载地址:Downloads | Apache SkyWalking
GitHub:https://github.com/apache/skywalking
文档:Welcome | Apache SkyWalking
中文文档:SkyWalking 文档中文版
三、链路追踪框架对比
1.Zipkin是Twitter开源的调用链分析工具,目前基于SpringCloud Sleuth得到了广泛应用,特点是轻量,使用部署简单。
2.Pinpoint是韩国开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能强大,接入端无代码侵入。
3.SkyWalking是中国开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。
4.CAT是大众点评开源的基于编码和配置的调用链路分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具。
项目 | Cat | Zipkin | SkyWalking |
---|---|---|---|
调用链可视化 | 有 | 有 | 有 |
聚合报表 | 非常丰富 | 少 | 较丰富 |
服务依赖图 | 简单 | 简单 | 好 |
埋点方式 | 侵入式 | 侵入式 | 非侵入式,字节码增强 |
VM监控指标 | 好 | 无 | 有 |
支持语言 | java/.net | 丰富 |
java/.net/php/go/node.js |
存储机制 | mysql(报表),本地文件/HDFS(调用链) | 内存、es、mysql等 | H2、es |
社区支持 | 主要在国内 | 国外主流 | Apache支持 |
使用案例 | 美团、携程 | 京东、阿里定制后不开源 | 华为、小米、。。。 |
APM | 是 | 否 | 是 |
开发基础 | eBay cal | Google Dapper | Google Dapper |
是否支持WebFlux | 否 | 是 | 是 |
四、主要功能特性
1.多种监控手段,可以通过语言探针和service mesh获得监控的数据
2.支持多种语言自动探针,包括Java、.Net Core和Node JS等
3.轻量高效,无需大数据平台和大量的服务器资源
4.模块化、UI、存储、集群管理都有多种机制可选
5.支持告警
6.优秀的可视化解决方案
五、服务端搭建
- SkyWalking agent和业务系统绑定在一起,负责收集各种监控数据
- SkyWalking oapservice是负责处理监控数据的,比如接受SkyWalking agent的监控数据,并存储在数据库中,接受SkyWalking Webapp的前端请求,从数据库查询数据,并返回数据给前端。SkyWalking oapservice通常以集群的形式存在。
- SkyWalking Webapp,前端界面,用于展示数据
- 用于存储监控数据的数据库,比如mysql,es等。
下载
目录结构
- webapp:ui前端(web监控页面)的jar包和配置文件
- oap-libs: 后台应用的jar包,以及它的依赖jar包,里边有一个server-starter-*.jar就是启动程序
- config: 启动后台应用程序的配置文件,是使用的各种配置
- logs: 日志信息
- bin: 各种脚本,一般使用脚本startup.*来启动web页面和对应的后台应用
- oapservice.*:默认使用的后台程序的启动脚本(使用的是默认启动模式,还支持其它模式,各模式区别见启动模式)
- oapServiceInit.*:默认init模式启动,在此模式下,OAP服务器启动以执行初始化工作,然后退出
- oapServiceNoInit.*: 使用NO init模式启动,在此模式下,OAP服务器不进行初始化
- webappService.*: UI前端启动的脚本
- startup.*: 组合脚本,同时启动oapService.* 、webappService.*脚本
- agent:
- skywalking-agent.jar:代理服务jar包
- config:代理服务启动时使用的配置文件
- plugins:包含多个插件,代理服务启动时会加载该目录下的所有插件(实际是各种jar包)
- optional-plugins: 可选插件,当需要支持某种功能时,比如SpringCloud Gateway,则需要把对应的jar包拷贝到plugins目录下
启动
- 双击startup.bat(linux下就启动startup.sh)
- 启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui : 默认端口号是8080,通常情况下在启动前会修改webapp目录下的配置文件,修改端口号。
- skywalking-oap-server服务启动后会暴露11800和12800端口,分别为收集监控数据的端口11800和接收前端请求的端口12800,修改端口可以修改config/application.yml
六、SkyWalking接入微服务
#指定skywalking-agent.jar所在位置
-javaagent:D:\SpringCloudAlibaba-2.2.7\
#指定服务名字
-DSW_AGENT_NAME=api-gateway
#指定collector连接地址
-DSW_AGENT_COLLECTOR_BACKED_SERVICES=127.0.0.1:11800
-DSW_AGENT_COLLECTOR_BACKED_SERVICES可以指定远程地址,但-javaagent必须绑定本机物理路径的skywalking-agent.jar
注意:此处存在bug,跟踪链路不显示gateway
拷贝agent/optional-plugins目录下的gateway插件到agent/plugins目录下,然后重启skywalking服务。
七、SkyWalking跨多个微服务跟踪
SkyWalking跨多个微服务跟踪,只需要每个微服务启动时添加javaagent参数即可。
八、持久化
默认使用的H2内存数据库存储。skywalking重启后数据就会丢失。
config/application.yml
基于mysql持久化
1.修改config目录下的application.yml,使用mysql作为持久化存储的数据库
2.修改mysql连接配置
3.创建swtest数据库,数据库下的表会在skywalking启动的时候自动创建。
4.重启skywalking,在启动时,oap-service会启动报错,查看log日志,发现缺少了mysql的驱动,是因为skywalking oap-libs目录下没有mysql驱动的jar包,在oap-libs目录下放置一个mysql驱动的jar即可。
5.再次重启即可。
九、自定义链路追踪
如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,可以使用如下代码
引入依赖
<!--SkyWalking工具类 跟使用的SkyWalking的版本保持一致-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.5.0</version>
</dependency>
@Trace
如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可。
@Tag
我们还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。
实现方式:在方法上增加@Tag或者@Tags。
@Tag 注解中,key = 方法名,value = returnedObj是固定值。
十、性能剖析
SkyWalking的性能分析,在根据服务名称,端点名称、以及相应的规则建立了任务列表后,在调用了此任务列表的端点后,skywalking会自动记录,剖析当前端口,生成剖析结果。
十一、SkyWalking集成日志框架
引入依赖
<!--apm-toolkit-logback-1.x-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.5.0</version>
</dependency>
添加logback-spring.xml文件,并配置%tid占位符
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds">
<!--引入SpringBoot默认的logback xml配置文件-->
<include resource="org/springframework/bootlogging/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.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"/>
</root>
</configuration>
SkyWalking通过grpc上报日志(需要v.8.4.0+)
gRPC报告程序可以将收集到的日志转发到SkyWalkingOAP服务器上。
logback-spring.xml中添加以下配置
<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>
修改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}
完整logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds">
<!--引入SpringBoot默认的logback xml配置文件-->
<include resource="org/springframework/bootlogging/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.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</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告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中。告警规则的定义分为两部分:
1.告警规则:他们定义了应该如何触发度量警报,应该考虑什么条件
2.Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知
告警规则
SkyWalking的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下:
1.过去三分钟内服务平均响应时间超过1秒。
2.过去2分钟服务成功率低于80%
3.过去3分钟内服务响应时间超过1s的百分比
4.服务实例在过去2分钟内平均响应时间超过1s,并且实例名称与正则表达式匹配
5.过去2分钟内端点平均响应时间超过1s
6.过去2分钟内数据库访问平均响应时间超过1s
7.过去2分钟内端点关系平均响应时间超过1s
这些预定义的告警规则,打开config/alarm-settings.yml文件即可看到
告警规则配置项的说明:
- Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
- Metrics name: 度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。
- Include names: 该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
- Exclude names: 该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为空)
- Threshold:阈值
- OP:操作符,目前支持>、<、=
- Period: 多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配
- Count: 在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报
- Silence period: 在时间N中触发报警后,在TN->TN+period这个阶段不告警。默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只触发一次
- message: 告警消息
Webhook(网络钩子)
webhook可以简单理解为是一种web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是Web层面的,所以当事件发生时,回调的不在是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件。当该事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。
SkyWalking的告警消息会通过HTTP请求进行发送,请求方法为POST,Content-Type为application/json,其JSON数据是基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>进行序列化的。
示例如下
[{
"scopeId": 1,
"scope": "SERVICE",
"name": "serviceA",
"id0": "12",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "alarmMessage xxxx",
"startTime": 1560524171000
}, {
"scopeId": 1,
"scope": "SERVICE",
"name": "serviceB",
"id0": "23",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "alarmMessage yyy",
"startTime": 1560524171000
}]
字段说明
- scopeId、scope:所有可用的scope都在org.apache.skywalking.oap.server.core.source.DefaultScopeDefine 中定义
- name: 目标scope实体名称
- id0: scope实体的 ID与名称匹配。使用关系scope时,它是源实体 ID。
- id1: 使用关系scope时,它将是目标实体 ID。否则,它是空的。
- ruleName: 告警规则名称
- alarmMessage:告警消息内容
- startTime:告警时间,以毫秒为单位,格式为时间戳
邮件告警功能实践
1.修改 config/alarm-settings.yml文件
2.编写回调接口,使用org.apache.skywalking.oap.server.core.alarm.AlarmMessage类作为参数接收。
十三、SkyWalking高可用
在大多数生产环境中,后端应用需要支持高吞吐量并且支持高可用来保证服务的稳定,所以你始终需要在生产环境进行集群管理。
SkyWalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行跟踪。
搭建一个skywalking oap集群需要:
- 至少一个nacos(也可以是nacos集群)
- 至少一个es/mysql(也可以是集群)
- 至少2个skywalking oap服务
- 至少一个ui(ui也可以集群多个,用nginx代理统一入口)
1.修改config/application.yml文件,使用nacos作为注册中心
2.修改nacos配置
3.可以选择性修改监听端口
4.修改存储策略,使用es或者mysql作为storage
5.修改mysql或者es配置
6.配置ui服务webapp.yml文件的listOfServers,写两个地址,中间以逗号分隔
7.启动Skywalking服务,指定jvm参数,中间以逗号分隔
-DSW_AGENT_COLLECTOR_BACKED_SERVICES=127.0.0.1:11800,127.0.0.1:11800