skywalking链路追踪
调研了市面上的监控方案,zipkin功能太弱,需要配合elk才能更好排查错误,CAT侵入太高,skywalking文档和社区不完善。但是skywalking功能是最强的。这篇文章的技术基础是java-agent探针技术,可以先看那文章了解原理。官方文档。
整个skywalking包括4个部分:数据存储依赖(es,数据库等等),上报后台APM,看板(skywalking-ui)、上报客户端。上报是基于grpc的,启动存储服务后,启动APM服务,APM监控两个端口11800负责接收上报、12800负责提供查询。启动看板,8080就是看板端口,前后端分离的,前端是单页应用,刷新会报404。启动服务设置agent上报数据。
大概就是这么个逻辑。
搭建流程:
本地环境需要下载8.7.0版本,下载地址是skywalking 为什么是8.7.0呢?因为8.7.0以后agent与apm服务端分离了,apm我是编译通过了,agent一直编译失败我tm日了狗了。
配置上报后台:
config/application.yml
cluster:
selector: ${SW_CLUSTER:standalone}
standalone:
......一大堆
core:
selector: ${SW_CORE:default}
default:
.....一大堆
storage:
selector: ${SW_STORAGE:elasticsearch7}
elasticsearch7:
nameSpace: ${SW_NAMESPACE:""}
# es地址
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:500}
socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30000}
user: ${SW_ES_USER:""}
password: ${SW_ES_PASSWORD:""}
.......一大堆
注:这些大写的SW_XXX占位符可以-DSW_XXX=xxxx设置,也可以通过设置环境变量设置。这点在docker启动的时候有体现。
docker run --name oap --restart always -d -e SW_STORAGE=elasticsearch7 -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 -p 11800:11800 apache/skywalking-oap-server:8.7.0-es7
注:这里的elasticsearch之所以能够按名访问是因为他们在同一个docker网络下面。
启动后就可以收集数据了。
配置看板:
webapp/webapp.yml
spring:
cloud:
gateway:
routes:
- id: oap-route
uri: lb://oap-service
predicates:
- Path=/graphql/**
discovery:
client:
simple:
instances:
oap-service:
- uri: http://127.0.0.1:12800
# - uri: http://<oap-host-1>:<oap-port1>
# - uri: http://<oap-host-2>:<oap-port2>
他是使用graphql风格的接口,同时做了负载均衡。看板后台将请求直接转发到收集后台的12800端口。启动后就访问8080就可以看到效果了。
或者你可以直接使用docker
docker run --name oap-ui --restart always -d -p 9400:8080 -e SW_OAP_ADDRESS=http://oap:12800 apache/skywalking-ui:8.7.0
配置agent:
agent/config/agent.config
# The service name in UI
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
# Backend service addresses.
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:10.10.2.241:11800}
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:10.10.2.241}
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}
注:日志上报在他的样例文件上是没有的需要自己添加。plugin.toolkit.log.grpc.reporter.XXXX。这也就意味着如果你需要使用docker它官方的agent镜像是不能适用与所有情况的,当然你可以将config目录和plugins目录挂载出来以解决插件选择与配置问题。
配置服务:
如果需要上报日志和打印traceId(tid)则需要添加对应的jar和配置文件
依赖引入:
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>${skywalking.version}</version>
</dependency>
logback-spring.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>app-b</contextName>
<property name="log.path" value="logs" />
<property name="log.maxHistory" value="15" />
<!-- 日志格式 -->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n" />
<!--输出到控制台-->
<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>${log.pattern}</pattern>
</layout>
</encoder>
</appender>
<!--输出到文件-->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/info/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<MaxHistory>${log.maxHistory}</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<!--格式化器-->
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${log.pattern}</pattern>
</layout>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--上报到skywalking-->
<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.TraceIdPatternLogbackLayout">
<pattern>${log.pattern}</pattern>
</layout>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="console" />
<appender-ref ref="grpc-log"/>
</root>
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="grpc-log"/>
</root>
</configuration>
访问启动时可以设置参数以更改一些配置。
-javaagent:pathto/skywalking-agent.jar
-DSW_AGENT_NAME=A_app
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=10.10.2.241:11800
-DSW_GRPC_LOG_SERVER_HOST=10.10.2.241
-DSW_GRPC_LOG_SERVER_PORT=11800
-Dagent.instance_uuid=实例id,如果不设置,每次都会生成新的。
完整如下:
java -jar -javaagent:pathto/skywalking-agent.jar -DSW_AGENT_NAME=A_app -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=10.10.2.241:11800 -DSW_GRPC_LOG_SERVER_HOST=10.10.2.241 -DSW_GRPC_LOG_SERVER_PORT=11800 demo.jar
注:SW_XXXX可以通过设置环境变量设置。
启动后再看版开启刷新可以看到你接入了,跑一下接口可以看到拓扑结构,链路和对应日志。
告警
skywaking的这项功能听说挺耗资源的,所有要谨慎。他有一个我非常中意的功能:webhook可以在告警的时候回调一个接口通知,这为告警带来了无限可能。可以接入一切通知。
config/alarm-settings.yml
rules:
# Rule unique name, must be ended with `_rule`.告警规则
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 3
silence-period: 5
message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.
webhooks:
- http://127.0.0.1/notify/
# - http://127.0.0.1/go-wechat/
规则与接口编写就不提了,你可以自己查阅官方文档。如果你希望在docker环境添加告警规则,你应该将/skywalking/ext-config目录挂载出来,然后将alarm-settings.yml放到你挂载的目录。如果你有新的告警逻辑,你应该将/skywalking/ext-libs挂载出来,然后将你的jar放到里面。(告警是APM服务端的功能)。
写的好,下次继续
李哥要转运维了啊