skywalking 是一个国产开源框架,2015 年由吴晟开源 , 2017 年加入 Apache 孵化器。skywalking 是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。SkyWalking 是观察性分析平台和应用性能管理系统,提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
官网:http://skywalking.apache.org/
OpenTracing 的组织,旨在推进调用链监控的一些规范和标准工作。
链路追踪框架对比
项目 | Cat | Zipkin | Skywalking |
---|---|---|---|
调用可视化 | 有 | 有 | 有 |
聚合报表 | 非常丰富 | 少 | 较丰富 |
服务依赖图 | 简单 | 简单 | 好 |
埋点方式 | 侵入式 | 侵入式 | 非侵入,字节码加强 |
VM监控指标 | 好 | 无 | 有 |
支持语言 | java/.net | 丰富 | java/.net/nodejs/php/go |
存储机制 | mysql/本地文件/HDFS | 内存/ES/mysql | h2/mysql/es/tidb |
社区支持 | 国内 | 国外 | Apache支持 |
使用案例 | 美团、携程、陆金所 | 京东、阿里 | 华为、小米、当当、微众银行 |
APM | 是 | 否 | 是 |
开发基础 | eBay cal | Google Dapper | Google Dapper |
是否支持webflux | 否 | 是 | 是 |
github stars | 12.3K | 12.2K | 18K |
主要功能
SkyWalking主要的几个组成模块:
构建后包括Skywalking后端和Web UI的目录:
├── bin
├── config
├── config-examples
├── LICENSE
├── licenses
├── logs
├── NOTICE
├── oap-libs
├── README.txt
├── tools
└── webapp
SkyWalking 整体架构如何?
整个架构,分成上、下、左、右四部分:
考虑到让描述更简单,我们舍弃掉 Metric 指标相关,而着重在 Tracing 链路相关功能。
目前阿里等云厂商也有各种Sass服务
官网新版的都是源码,需要自己去构建
服务 包括以下部分
DROP
DATABASE IF EXISTS `swtest`;
CREATE
DATABASE `swtest` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
storage:
selector: ${SW_STORAGE:mysql}
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://xxx:3306/swtest?rewriteBatchedStatements=true"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:xxx}
skywalking国内下载:
https://mirrors.cloud.tencent.com/apache/skywalking
https://archive.apache.org/dist/skywalking/
./startup.sh
wget http://maven.aliyun.com/nexus/content/groups/public/mysql/mysql-connector-java/5.1.48/mysql-connector-java-5.1.48.jar
wget http://maven.aliyun.com/nexus/content/groups/public/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar
**镜像地址:**https://hub.docker.com/r/apache/skywalking-java-agent
docker run --name oap -d --restart always \
-p 11800:11800 \
-p 12800:12800 \
-e SW_STORAGE=mysql \
-e "SW_JDBC_URL=jdbc:mysql://xxx:3306/swtest?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true" \
-e SW_DATA_SOURCE_USER=root \
-e SW_DATA_SOURCE_PASSWORD=xpccyc_2022 \
apache/skywalking-oap-server:8.9.1
docker run --name oap -d --restart always \
-e TZ=Asia/Shanghai \
-p 12800:12800 \
-p 11800:11800 \
--link elasticsearch:elasticsearch \
-e SW_STORAGE=elasticsearch \
-e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 \
apache/skywalking-oap-server:6.6.0-es7
docker run -d --name oap-ui \
--restart=always \
-e TZ=Asia/Shanghai \
-p 8868:8080 \
--link oap:oap \
-e SW_OAP_ADDRESS=http://xxx:12800 \
apache/skywalking-ui
elasticsearch
作为 skywalking 的存储,保存链路和日志数据等oap
数据接收和分析 Observability Analysis Platformui
web端的数据展示# 创建配置文件保存的目录
mkdir -p /data/docker/admin/skywalking
# 切换到刚创建的目录
cd /data/docker/admin/skywalking
# 将下面的 docker-compose.yml 文件保存到这个目录
vi docker-compose.yml
# 拉去镜像并启动
docker-compose up -d
# 查看日志
docker-compose logs -f
docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.1
container_name: elasticsearch
restart: always
ports:
- 9200:9200
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- TZ=Asia/Shanghai
ulimits:
memlock:
soft: -1
hard: -1
oap:
image: apache/skywalking-oap-server:8.7.0-es7
container_name: oap
depends_on:
- elasticsearch
links:
- elasticsearch
restart: always
ports:
- 11800:11800
- 12800:12800
healthcheck:
test: ["CMD-SHELL", "/skywalking/bin/swctl"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
environment:
TZ: Asia/Shanghai
SW_STORAGE: elasticsearch7
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
ui:
image: apache/skywalking-ui:8.7.0
container_name: ui
depends_on:
- oap
links:
- oap
restart: always
ports:
- 8088:8080
environment:
TZ: Asia/Shanghai
SW_OAP_ADDRESS: http://oap:12800
http://IP:8080
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TcTYQ9d2-1689842932926)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220915191747007.png)]
通过设置启动脚本添加请求启动参数,字节码注入的方式
agent发行包包含在Apache官方发行版中。最新的agent包结构如下。
+-- agent
+-- activations
apm-toolkit-log4j-1.x-activation.jar
apm-toolkit-log4j-2.x-activation.jar
apm-toolkit-logback-1.x-activation.jar
...
+-- config
agent.config
+-- plugins
apm-dubbo-plugin.jar
apm-feign-default-http-9.x.jar
apm-httpClient-4.x-plugin.jar
.....
+-- optional-plugins
apm-gson-2.x-plugin.jar
.....
+-- bootstrap-plugins
jdk-http-plugin.jar
.....
+-- logs
skywalking-agent.jar
skywalking的java agent迁移到了新仓库
https://github.com/apache/skywalking-java
下载后使用idea打开
新版:需要下载源码自己打包获取skywalking-agent.jar
有一些proto
的文件需要生成,使用如下命令行编译生成
mvn clean package -DskipTests
老版:https://archive.apache.org/dist/skywalking/8.2.0/apache-skywalking-apm-8.2.0.tar.gz
nohup java -javaagent:/data/init/skywalking-agent.jar \
-Dskywalking.agent.service_name=${ENV}::$SERVER_NAME \
-Dskywalking.collector.backend_service=10.32.120.156:11800 \
-jar -Xms256m -Xmx512m -Dspring.profiles.active=${ENV} $JAR_NAME >> /data/project/$SERVER_NAME/info.log 2>&1 &
老版本:注意:此处存在 bug,跟踪链路不显示 gateway
拷贝 skywalking-agent/optional-plugins 目录下的 gateway 插件到 agent/plugins 目录
如果我们希望对项目中的业务方法实现链路追踪,方便排查问题,可以导入如下依赖版本号尽量和skywalking保持一致
它可以将任意业务方法加入到skywalkingUI界面中的链路追踪,可以看到自定义的链路节点耗费时间并包括参数返回值等常规信息
org.apache.skywalking
apm-toolkit-trace
${skywalking.version}
代码中使用traceId
@RequestMapping("/list")
public List list(){
//TraceContext可以绑定key-value
TraceContext.putCorrelation("name", "fox");
Optional op = TraceContext.getCorrelation("name");
log.info("name = {} ", op.get());
//获取跟踪的traceId
String traceId = TraceContext.traceId();
log.info("traceId = {} ", traceId);
return userService.list();
}
如果一个业务方法想在 ui 界面的跟踪链路上显示出来,只需要在业务方法上加上 @Trace 注解即可
我们还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。实现方式:在方法上增加 @Tag 或者 @Tags。
@Trace
@Tag(key = "list", value = "returnedObj")
public List 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);
}
我们需要在日志中记录下来每次请求的唯一标识(trace-id),这样就可以在SkyWalking定位到有问题的trace-id,然后通过这个trace-id我们就可以通过日志系统去定位到相关的日志,从而发现并解决问题。
引入apm-toolkit-logback-1.x依赖
org.apache.skywalking
apm-toolkit-logback-1.x
${skywalking.version}
日志配置
${log.pattern}
${log.path}/info.log
${log.path}/info.%d{yyyy-MM-dd}.log
10
${log.pattern}
INFO
ACCEPT
DENY
${log.path}/error.log
${log.path}/error.%d{yyyy-MM-dd}.log
30
${log.pattern}
ERROR
ACCEPT
DENY
打开 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 在本地的可以不配
Apache SkyWalking告警是由一组规则驱动,这些规则定义在config/alarm-settings.yml
文件中。
告警规则的定义分为三部分。
告警规则有两种类型,单独规则(Individual Rules)和复合规则(Composite Rules),复合规则是单独规则的组合。
单独规则主要有以下几点:
_rule
结尾。标签的设置必须把数据存储在meter-system中,例如:Prometheus, Micrometer。以上四个标签设置必须实现LabeledValueHolder
接口。
对于多个值指标,例如percentile,阈值是一个数组。像value1
value2
value3
value4
value5
这样描述。
每个值可以作为度量中每个值的阈值。如果不想通过此值或某些值触发警报,则将值设置为 -
。
例如在percentile中,value1
是P50的阈值,value2
是P75的阈值,那么-,-,value3, value4, value5
的意思是,没有阈值的P50和P75的percentile告警规则。
>
, >=
, <
, <=
, =
。true
或者false
,指定规则是否可以发送告警,或者仅作为复合规则的条件。举个例子:
rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 2
silence-period: 10
message: 服务【{name}】的平均响应时间在最近10分钟内有2分钟超过1秒
service_instance_resp_time_rule:
metrics-name: service_instance_resp_time
op: ">"
threshold: 1000
period: 10
count: 2
silence-period: 10
message: 实例【{name}】的平均响应时间在最近10分钟内有2分钟超过1秒
endpoint_resp_time_rule:
metrics-name: endpoint_avg
threshold: 1000
op: ">"
period: 10
count: 2
message: 端点【{name}】的平均响应时间在最近10分钟内有2分钟超过1秒
复合规则仅适用于针对相同实体级别的告警规则,例如都是服务级别的告警规则:service_percent_rule && service_resp_time_percentile_rule
。
不可以编写不同实体级别的告警规则,例如服务级别的一个告警规则和端点级别的一个规则:service_percent_rule && endpoint_percent_rule
。
复合规则主要有以下几点:
_rule
结尾。&&
, ||
, ()
操作符。举个例子:
rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 2
silence-period: 10
message: 服务【{name}】的平均响应时间在最近10分钟内有2分钟超过1秒
service_sla_rule:
metrics-name: service_sla
op: "<"
threshold: 8000
period: 10
count: 2
silence-period: 10
message: 服务【{name}】的成功率在最近10分钟内有2分钟低于80%
composite-rules:
comp_rule:
expression: service_resp_time_rule && service_sla_rule
message: 服务【{name}】在最近10分钟内有2分钟超过1秒平均响应时间超过1秒并且成功率低于80%
Webhook 要求一个点对点的 Web 容器。告警的消息会通过 HTTP 请求进行发送,请求方法为 POST
,Content-Type
为 application/json
,JSON 格式包含以下信息:
alarm-settings.yml
中配置的规则名。举个例子:
[{
"scopeId": 1,
"scope": "SERVICE",
"name": "one-more-service",
"id0": "b3JkZXItY2VudGVyLXNlYXJjaC1hcGk=.1",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "服务【one-more-service】的平均响应时间在最近10分钟内有2分钟超过1秒",
"startTime": 1617670815000
}, {
"scopeId": 2,
"scope": "SERVICE_INSTANCE",
"name": "[email protected] of one-more-service",
"id0": "dWF0LWxib2Mtc2VydmljZQ==.1_ZTRiMzEyNjJhY2FhNDdlZjkyYTIyYjZhMmI4YTdjYjFAMTcyLjI0LjMwLjEzOA==",
"id1": "",
"ruleName": "instance_jvm_young_gc_count_rule",
"alarmMessage": "实例【[email protected] of one-more-service】的YoungGC次数在最近10分钟内有2分钟超过10次",
"startTime": 1617670815000
}, {
"scopeId": 3,
"scope": "ENDPOINT",
"name": "/one/more/endpoint in one-more-service",
"id0": "b25lcGllY2UtYXBp.1_L3RlYWNoZXIvc3R1ZGVudC92aXBsZXNzb25z",
"id1": "",
"ruleName": "endpoint_resp_time_rule",
"alarmMessage": "端点【/one/more/endpoint in one-more-service】的平均响应时间在最近10分钟内有2分钟超过1秒",
"startTime": 1617670815000
}]
告警消息将使用 Protobuf
类型通过gRPC远程方法发送。消息格式的关键信息定义如下:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.apache.skywalking.oap.server.core.alarm.grpc";
service AlarmService {
rpc doAlarm (stream AlarmMessage) returns (Response) {
}
}
message AlarmMessage {
int64 scopeId = 1;
string scope = 2;
string name = 3;
string id0 = 4;
string id1 = 5;
string ruleName = 6;
string alarmMessage = 7;
int64 startTime = 8;
}
message Response {
}
您需要遵循传入Webhooks入门指南并创建新的Webhooks。
如果您按以下方式配置了Slack Incoming Webhooks,则告警消息将按 Content-Type
为 application/json
通过HTTP的 POST
方式发送。
举个例子:
slackHooks:
textTemplate: |-
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":alarm_clock: *Apache Skywalking Alarm* \n **%s**."
}
}
webhooks:
- https://hooks.slack.com/services/x/y/z
只有微信的企业版才支持 Webhooks ,如何使用微信的 Webhooks 可参见如何配置群机器人。
如果您按以下方式配置了微信的 Webhooks ,则告警消息将按 Content-Type
为 application/json
通过HTTP的 POST
方式发送。
举个例子:
wechatHooks:
textTemplate: |-
{
"msgtype": "text",
"text": {
"content": "Apache SkyWalking 告警: \n %s."
}
}
webhooks:
- https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=dummy_key
您需要遵循自定义机器人开放并创建新的Webhooks。为了安全起见,您可以为Webhook网址配置可选的密钥。
如果您按以下方式配置了钉钉的 Webhooks ,则告警消息将按 Content-Type
为 application/json
通过HTTP的 POST
方式发送。
举个例子:
dingtalkHooks:
textTemplate: |-
{
"msgtype": "text",
"text": {
"content": "Apache SkyWalking 告警: \n %s."
}
}
webhooks:
- url: https://oapi.dingtalk.com/robot/send?access_token=dummy_token
secret: dummysecret
Activate MySQL as storage, and set storage provider to mysql.
NOTE: MySQL driver is NOT allowed in Apache official distribution and source codes. Please download the MySQL driver on your own. Copy the connection driver jar to oap-libs
.
wget http://maven.aliyun.com/nexus/content/groups/public/maven2/mysql/mysql-connector-java/5.1.48/mysql-connector-java-5.1.48.jar
wget http://maven.aliyun.com/nexus/content/groups/public/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar
Skywalking部署简单,新版UI更加好用。skywalking在链路追踪、告警和性能指标统计等方面能帮助开发和运维快速定位问题,在半年多的使用中,发现过慢SQL语句、程序bug和报错等等。skywalking推送的告警更使各个项目的负责人对自己负责业务的性能指标做到心中有数,有问题及时优化。
https://xie.infoq.cn/article/9ed9c65315251d0b39614d4d0
https://skywalking.apache.org/zh/2020-04-19-skywalking-quick-start/#