网站首页 > 精选教程 正文
本章内容
Skywalking简介
Skywalking是一款开源的应用性能监控系统,包括链路追踪、日志监控、性能剖析以及告警处理等。
Skywalking支持SpringBoot、SpringCloud、Dubbo等主流框架,代码无侵入,通信方式采用gRPC,性能较好,实现方式为Java Agent(探针)。
Skywalking相比于Sleuth+Zipkin的优势:
- Skywalking采用字节码增强的技术实现代码无侵入,ZipKin代码侵入性比较高。
- Skywalking功能比较丰富,报表统计、UI界面更加人性化。
建议优先选择Skywalking。
Skywalking架构
Skywalking总体架构,如图所示:
其中:
- Agent:负责收集日志数据,并将收集的数据通过gRPC协议传输给OAP服务器。
- OAP:负责接收Agent发送的Tracing和Metrics信息,对数据进行分析(Analysis Core)后存储到外部存储器(Storage)中,并对外提供查询(Query)服务。
- UI:负责展示查询的Skywalking信息,如:调用链路、指标信息、性能诊断信息等。
- Storage:负责数据存储,支持多种存储类型(如:MySQL、Elasticsearch、TiDB等)。
Skywalking执行流程,如图所示:
处理流程:
- 1)通过探针(Agent)技术对Java应用数据进行采集,并通过gRPC协议将采集信息传输到Skywalking服务端(即:OAP)。
- 2)Skywalking服务端接收到采集数据后,利用各种插件对采集数据进行分析和逻辑处理(如:JVM相关插件用来处理上报到Skywalking服务端的JVM信息,数据库插件用来分析访问数据库的信息),并将分析、处理后的数据存入数据存储层。
- 3)SkyWalking数据存储层支持多种主流数据库(如:Elasticsearch、MySQL、H2、TiDB等),推荐使用ElasticSearch。
- 4)通过Skywalking Rocketbot对采集数据进行多方面展示,如:仪表盘、拓扑图、追踪、性能剖析、日志、告警等。
服务端搭建
下载安装包
Skywalking下载地址:https://skywalking.apache.org/downloads/
如图所示:
本文中选择的版本为:v8.8.0。
完整目录结构如下:
其中:
- bin:服务端启动脚本。
- config:配置文件目录。
- logs:日志目录。
- oap-libs:OAP服务所需依赖目录。
- webapp:UI服务目录。
修改配置
OAP服务配置信息在config/application.yml文件中进行配置,修改内容:
cluster:
# selector默认为:standalone,更新配置中心为:nacos
selector: ${SW_CLUSTER:nacos}
standalone:
# ...
nacos:
serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
# Nacos Configuration namespace
namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}
# Nacos auth username
username: ${SW_CLUSTER_NACOS_USERNAME:""}
password: ${SW_CLUSTER_NACOS_PASSWORD:""}
# Nacos auth accessKey
accessKey: ${SW_CLUSTER_NACOS_ACCESSKEY:""}
secretKey: ${SW_CLUSTER_NACOS_SECRETKEY:""}
Skywalking UI服务配置信息在webapp/webapp/yml文件中进行配置,修改内容:
server:
port: 8889
启动服务
进入bin目录,执行:./startup.sh启动OAP服务和Skywalking UI服务。
显示如下信息表示启动成功:
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!
启动后,注意查看logs文件夹中的启动日志信息,确保启动没有异常。
访问:http://localhost:8889进入Skywalking UI界面。如图所示:
Nacos注册中心信息:
注意:Skywalking多种注册中心,除了Nacos外,还支持Zookeeper、Kubernetes、Consul、Etcd等。
客户端使用
监控服务
示例服务:
- springboot-nacos-gateway:网关。
- springboot-nacos-order:订单服务。
- springboot-nacos-stock:库存服务。
从Skywalking官网下载Java Agent,Java应用启动时,添加如下启动参数(VM Options):
-javaagent:/Users/wuzp/Desktop/learn/agent/skywalking-agent/skywalking-agent.jar
-Dskywalking.agent.service_name=springboot-nacos-gateway
-Dskywalking.collector.backend_service=127.0.0.1:11800
其中:
- -javaagent:指定Skywalking中agent的(skywalking-agent.jar)路径。
- -Dskywalking.agent.service_name:指定在skywalking中的服务名称,一般是微服务的spring.application.name。
- -Dskywalking.collector.backend_service:指定OAP服务绑定的地址,OAP服务默认的端口为11800,因此配置为:127.0.0.1:11800
如图所示:
Skywalking UI展示信息
三个服务启动后,访问http://127.0.0.1:9080/order/query。Skywalking UI显示信息:
仪表盘-Service信息:
仪表盘-Instance信息:
仪表盘-Endpoint信息:
拓扑图:
追踪信息:
统计信息:
Skywalking UI展示信息常见问题:
- OAP服务启动异常,如:堆内存溢出、元空间溢出等,因此,启动OAP服务后注意查看启动日志。
- 时间和时区超出范围,注意检查右下角的时间段以及时区是否正确。
- 数据更新延迟,页面数据刷新频率在右上角处设置,如果发现数据无法及时更新,可以等待指定时长后再查看。
监控方法
添加依赖:
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.15.0</version>
</dependency>
添加注解:
@Trace
@PostMapping("create")
public String create(){
log.info("create order traceId:{},spanId:{}",TraceContext.traceId(),TraceContext.spanId());
log.info("减扣库存");
stockApi.create();
log.info("创建订单");
return "create order success";
}
其中:方法级监控还可以通过@Tag注解获取方法入参和返回值等信息。Skywalking UI展示信息与服务级监控一样,这里就不展示了。
数据库持久化
本文中,数据存储层使用的是默认配置H2,如果需要使用其他存储系统(如:Elasticsearch、MySQL等),切换配置即可。
storage:
selector: ${SW_STORAGE:h2}
性能剖析
性能剖析是利用方法堆栈快照对方法的执行情况进行分析和汇总,对代码执行速度进行估算。
性能剖析激活时,会对指定线程周期性的进行线程堆栈快照,并将所有的快照进行汇总分析,如果两个连续的快照含有同样的方法栈,则说明此栈中的方法大概率在这个时间间隔内都处于执行状态。通过这种连续快照的时间间隔累加成为估算的方法执行时间。
使用示例
示例方法:
/**
* @author 南秋同学
*/
@Slf4j
@RestController
@RequestMapping("/order/")
public class OrderController {
@Resource
private StockApi stockApi;
@SneakyThrows
@GetMapping("query")
public String query(){
log.info("query order traceId:{},spanId:{}",TraceContext.traceId(),TraceContext.spanId());
log.info("查询库存");
stockApi.query();
Thread.sleep(1000);
log.info("订单查询");
return "query order success";
}
}
新建任务,如图所示:
其中,最大采样数量为5次,因此,连续请求/order/query接口5次。
注意:端点名称为仪表盘中展示的端点信息,如:GET:/order/query。
Skywalking UI展示信息,如图所示:
线程堆栈信息,如图所示:
日志监控
在开发过程中,可以通过记录当前调用链路的traceId,根据traceId从Skywalking前端界面中找到当前链路对应的调用记录,对问题进行定位与分析。
使用示例
添加依赖:
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.15.0</version>
</dependency>
以logback为例,添加日志配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds">
<!-- 控制台打印TraceId -->
<appender name="STDOUT" 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="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<neverBlock>true</neverBlock>
<appender-ref ref="STDOUT"/>
</appender>
<!-- 将日志信息通过gRPC协议传输到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.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="grpc-log" />
<appender-ref ref="ASYNC"/>
</root>
</configuration>
注意:如果skywalking-agent与OAP服务分属于不同的服务器,则需要在skywalking-agent的config/agent.config文件中添加如下内容:
# 指定上报日志数据的目标主机的IP
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:OAP服务地址}
# 指定上报日志数据的目标主机的Port
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}
控制台信息,如图所示:
Skywalking UI展示信息,如图所示:
告警处理
Skywalking根据指定时间周期内收集的链路追踪数据与配置的告警规则(如:服务响应时间、服务响应时间百分比)进行判断,如果达到阈值,则发送相应的告警信息。
告警规则在config/alarm-settings.yml文件中定义,主要包含两部分内容:
- 告警规则(即:触发条件)。
- 网络钩子(即:触发告警后对应的处理方法)。
告警规则
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.
service_sla_rule:
# Metrics value need to be long, double or int
metrics-name: service_sla
op: "<"
threshold: 8000
# The length of time to evaluate the metrics
period: 10
# How many times after the metrics match the condition, will trigger alarm
count: 2
# How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.
silence-period: 3
message: Successful rate of service {name} is lower than 80% in 2 minutes of last 10 minutes
service_resp_time_percentile_rule:
# Metrics value need to be long, double or int
metrics-name: service_percentile
op: ">"
threshold: 1000,1000,1000,1000,1000
period: 10
count: 3
silence-period: 5
message: Percentile response time of service {name} alarm in 3 minutes of last 10 minutes, due to more than one condition of p50 > 1000, p75 > 1000, p90 > 1000, p95 > 1000, p99 > 1000
service_instance_resp_time_rule:
metrics-name: service_instance_resp_time
op: ">"
threshold: 1000
period: 10
count: 2
silence-period: 5
message: Response time of service instance {name} is more than 1000ms in 2 minutes of last 10 minutes
database_access_resp_time_rule:
metrics-name: database_access_resp_time
threshold: 1000
op: ">"
period: 10
count: 2
message: Response time of database access {name} is more than 1000ms in 2 minutes of last 10 minutes
endpoint_relation_resp_time_rule:
metrics-name: endpoint_relation_resp_time
threshold: 1000
op: ">"
period: 10
count: 2
message: Response time of endpoint relation {name} is more than 1000ms in 2 minutes of last 10 minutes
其中:
- Rule name:规则名称,以_rule结尾。如:service_resp_time_rule。
- Metrics name:oal脚本中的度量名称,目前只支持long、double和int类型。
- Include names:告警规则生效的服务列表。
- Exclude names:告警规则排除(即:不生效)的服务列表。
- Threshold:阈值。
- OP:操作符,目前支持 >、<、=。
- Period:校验周期(即:一个时间窗口),单位为分钟。
- Count:在一个校验周期中,如果Values超过设定的阀值Threshold,且数量达到Count值,则需要发送告警消息。
- Silence period:沉默周期,即:在一个沉默周期内,相同的告警信息只会被触发一次。
- message:告警消息。
告警规则(Skywalking-v8.8.0版本):
- service_resp_time_rule:在一个校验周期(10分钟)内,如果服务平均响应时间超过1秒的次数达到3次,则发送告警消息。
- service_sla_rule:在一个校验周期(10分钟)内,如果在最近的2分钟内服务的成功率低于80%,则发送告警消息。
- service_resp_time_percentile_rule:在一个校验周期(10分钟)内,如果最近的3分钟内90%的服务响应时长超过1秒,则发送告警消息。
- service_instance_resp_time_rule:在一个校验周期(10分钟)内,如果在最近的2分钟内服务实例的平均响应时长超过1秒,则发送告警消息。
- database_access_resp_time_rule:在一个校验周期(10分钟)内,如果在最近的2分钟内数据库的平均响应时长超过1秒,则发送告警消息。
- endpoint_relation_resp_time_rule:在一个校验周期(10分钟)内,如果在最近的2分钟内关联端点之间的平均响应时长超过1秒,则发送告警消息。
webhooks
webhook是为告警规则配置的回调处理。即:当触发上述规则告警时,Skywalking会调用配置的webhook。开发人员可以定制回调处理方法,如:发送邮件、微信、钉钉等,通知运维人员进行处理。
Skywalking的告警消息通过HTTP请求进行发送。webhooks规则:
- 请求类型为POST。
- 内容格式(Content-Type)为application/json。
- 参数格式为List<AlarmMessage>的JSON数据。
JSON数据示例:
[{
"scopeId": 1,
"scope": "SERVICE_INSTANCE",
"name": "serviceA",
"id0": 100,
"id1": 0,
"ruleName": "service_resp_time_rule",
"alarmMessage": "alarmMessage test",
"startTime": 1560524171000
}]
其中:
- scopeId、scope:所有可用的Scope,在org.apache.skywalking.oap.server.core.source.DefaultScopeDefine中声明。
- name:目标Scope实体名称。
- id0:Scope实体ID。
- id1:预留字段,暂未使用。
- ruleName:告警规则名称。
- alarmMessage:告警消息。
- startTime:告警时间,格式为时间戳。
使用示例
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
1)定义消息接收对象
/**
* @author 南秋同学
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AlarmMessage {
private int scopeId;
private String scope;
private String name;
private String id0;
private String id1;
private String ruleName;
private String alarmMessage;
private long startTime;
}
2)定义接收Skywalking告警通知方法
/**
* @author 南秋同学
* 告警服务
*/
@Slf4j
@RestController
@RequestMapping("/alarm/")
public class AlarmController {
@Resource
private JavaMailSender sender;
@Value("${spring.mail.username}")
private String from;
/**
* 接收Skywalking的告警通知并发送告警信息至邮箱
* @param alarmMessages 告警消息
*/
@PostMapping("receive")
public void receive(@RequestBody List<AlarmMessage> alarmMessages){
SimpleMailMessage message = new SimpleMailMessage();
// 发送者邮箱
message.setFrom(from);
// 接收者邮箱
message.setTo(from);
// 主题
message.setSubject("Skywalking告警邮件");
String content = getContent(alarmMessages);
// 邮件内容
message.setText(content);
sender.send(message);
log.info("告警邮件已发送");
}
private String getContent(List<AlarmMessage> alarmMessages) {
StringBuilder sb = new StringBuilder();
for (AlarmMessage alarmMessage : alarmMessages) {
sb.append("scopeId: ").append(alarmMessage.getScopeId())
.append("\nscope: ").append(alarmMessage.getScope())
.append("\n目标Scope实体名称: ").append(alarmMessage.getName())
.append("\nScope实体ID: ").append(alarmMessage.getId0())
.append("\nid1: ").append(alarmMessage.getId1())
.append("\n告警规则名称: ").append(alarmMessage.getRuleName())
.append("\n告警消息内容: ").append(alarmMessage.getAlarmMessage())
.append("\n告警时间: ").append(alarmMessage.getStartTime())
.append("\n\n---------------\n\n");
}
return sb.toString();
}
}
3)配置邮件信息
spring:
mail:
host: smtp.126.com
#发送者邮箱账号
username: xxxxxx@126.com
#发送者密码
password: xxxxxx
default-encoding: utf-8
#端口号465
port: 465
protocol: smtp
properties:
mail:
debug:
false
smtp:
socketFactory:
class: javax.net.ssl.SSLSocketFactory
4)配置webhooks(config/alarm-settings.yml)
webhooks:
- http://127.0.0.1:9080/alarm/receive/
【阅读推荐】
更多精彩内容,如:
- Redis系列
- 数据结构与算法系列
- Nacos系列
- MySQL系列
- JVM系列
- Kafka系列
请移步【南秋同学】个人主页进行查阅。内容持续更新中......
【作者简介】
一枚热爱技术和生活的老贝比,专注于Java领域,关注【南秋同学】带你一起学习成长~
猜你喜欢
- 2024-12-02 jacoco 生成单测覆盖率报告
- 2024-12-02 BOS分布式链路追踪产品揭秘
- 2024-12-02 如何在字节码层面实现方法拦截:探索 Java Agent 与 ASM 的魅力
- 2024-12-02 非Spring管理Bean如何添加AOP呢?
- 2024-12-02 Flink实时计算在贝壳的实践及应用
- 2024-12-02 K8S官方java客户端之四:内部应用
- 2024-12-02 All in one:如何搭建端到端可观测体系
- 2024-12-02 skywalking快速入门
- 2024-12-02 几款流行监控系统简介
- 2024-12-02 OpenTelemetry系列 四| 如何使用JavaAgent来实现无侵入的调用链
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)