SpringCloudAliBaba篇之SkyWalking:轻松实现应用性能监控

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringCloudAliBaba篇之SkyWalking:轻松实现应用性能监控

1、skywalking是什么

skywalking是一个国产开源框架,2015年由吴晟开源,2017年加入Apache孵化器。skywalking是分布式系统的应用程序的性能监视工具,专为微服务、云原生架构和基于容器(Docker、k8s,Mesos)架构而设计。它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

官网: http://skywalking.apache.org

下载: https://skywalking.apache.org/downloads/

Github: https://github.com/apache/skywalking

文档: https://skyapm.github.io/document-cn-translation-of-skywalking/

1.2、链路追踪框架对比

1、Zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单

2、Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能强大,接入端无代码侵入。

3、SkyWalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。

4、CAT是大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一些列监控平台工具。

1.3、skywalking的主要功能特性

1、多种监控手段,可以通过语言探针和service mesh获得监控的数据

2、支持多种语言的自动探针、包括java 、.NET Core 和 Node.JS

3、轻量高效,无需大数据平台和大量的服务器资源

4、模块化,UI,存储、集群管理都有多种机制可选

5、支持告警

6、优秀的可视化解决方案

2、skywalking环境搭建部署

  • skywalking agent和业务系统绑定在一起,负责收集各种监控数据
  • skywalking oapservice是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中;接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。skywalking oapservice通常以集群的形式存在。
  • skywalking webapp 前端界面,用于展示数据。
  • 用于存储监控数据的数据库,比如mysql,elasticsearch等

2.1、下载skywalking

下载地址:

https://archive.apache.org/dist/skywalking/8.5.0/【我这里用windows演示】

  • webapp: UI前端(web监控页面)的jar包和配置文件
  • oap-libs: 后台应用的jar包,以及它的依赖jar包
  • config: 启动后台应用程序的配置文件
  • 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包拷贝到plugiins目录下;

2.2、搭建SkyWalking OAP服务

1、修改UI地址webapp\webapp.yml端口号,由于8080我们经常需要用到,所以为了避免以后冲突,我们进行修改

server:
  port: 8810
collector:
  path: /graphql
  ribbon:
    ReadTimeout: 10000
    # Point to all backend's restHost:restPort, split by ,
    listOfServers: 127.0.0.1:12800

双击启动bin/startup.bat

启动成功后,日志存储在logs目录

启动成功后会启动两个服务,一个是skywalking-aop-server,一个是skywalking-web-ui

skywalking-aop-server服务启动后会暴露11800和12800两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/application.yml

我们进行访问:localhost:8810

2.3、skywalking—接入微服务

1、在运行的程序配置jvm参数

# 你的 skywalking-agent.jar包地址
-javaagent:D:\a-mysource\apache-skywalking\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=springboot-skywalking-demo
#你的skywalking-aop-server地址及端口号
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800

启动成功后,随便对一个接口进行访问,然后刷新我们的skywalking UI界面

注意:此处存在bug,跟踪链路不显示gateway

拷贝agent/optional-plugins目录下的gateway插件到agent/plugins目录

然后进行重启(服务也需重启)

然后我们来看看拓补图(服务之间的错综复杂调用关系图)

用户调用网关服务,网关服务转发到我们需要调用的服务

追踪

可以看到我们请求经过的一些具体信息

2.4、skywalking—接入多个微服务

将我们之前的服务按上述步骤,配置jvm参数即可

# 你的 skywalking-agent.jar包地址
-javaagent:D:\a-mysource\apache-skywalking\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=springboot-skywalking-demo
#你的skywalking-aop-server地址及端口号
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800

然后打开UI界面

成功多了很多指标,对应服务也都添加进来了

我们再看拓补图

关系也错综复杂起来了

  • 用户
  • 网关
  • order-service服务
  • 数据库
  • stock-service服务
  • 数据库

我们再看追踪

可以精确定位到哪个服务出的错误。

3、skywalking持久化跟踪数据

默认使用的是H2数据库存储 , 存储在我们的内存中

config/application.yml

3.1、基于mysql持久化

1、修改config目录下的application.yml. 使用mysql作为持久化的残酷

2、修改mysql连接配置

3、创建数据库swtest ,至于表我们不用去关心,它会在我们启动的时候自动为我们建表

4、添加mysql驱动jar包到oap-libs里面

5、进行重启

发现自动为我们创建了很多表

这个时候我们关闭再打开skywaking程序就发现原有的数据都还存在。

4、自定义skywalking链路追踪

4.1、@Trace注解

如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题。可以使用如下的操作

1、引入依赖

<!--skywalking 工具类,为了自定义链路追踪-->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.5.0</version>
</dependency>

2、只需要在业务方法上加入一个注解即可

@Trace
public String hello(String str) {
    return str;
}

可以看到我们的业务方法也进入到了链路当中

4.2、@Tags或@Tag注解

还可以为追踪链路增加其额外的信息,比如记录参数和返回信息。实现方式:在方法上增加@Tag和@Tags。

key = 名字,value=returnObj 返回值 arg[0] 参数

@Trace
@Tags({@Tag(key = "string",value = "returnedObj"),@Tag(key = "param",value = "arg[0]")})
public String hello(String str) {
    return str;
}

5、skywalking性能剖析

对一个服务的一个接口进行,性能分析,最大采样数即最少访问次数

请求5次以上然后进行刷新

看看具体信息

可以准确定位我们消耗资源的问题所在,因为我在代码中加入了休眠。

6、skywalking日志

1、我们在需要添加日志的服务里引入依赖

<!--apm‐toolkit‐logback‐1.x  日志 -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.5.0</version>
</dependency>

2、添加文件logback-spring.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!-- 引入Spring Boot 默认的 logback xml 配置文件-->
    <include resource="org/springframework/boot/logging/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.TraceIdPatternLogbackLayout">
                <Pattern>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
            </layout>
        </encoder>
    </appender>
    <!--设置Appender-->
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>
</configuration>

3、启动项目

可以根据tid定位到对应的链路信息,搜索即可

4、skywalking通过grpc上报日志(需要v8.4.0+)

grpc报告程序可以将收集到的日志转发到skywalking oap服务器上

logback-spring.xml中添加后的全部内容为

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引入 Spring Boot 默认的 logback XML 配置文件 -->
    <include resource="org/springframework/boot/logging/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.TraceIdPatternLogbackLayout">
                <Pattern>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</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>
    <!--设置 Appender-->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="grpc-log"/>
    </root>
</configuration>

重新启动

注意:如果时部署在服务器上的话,日志可能不能正常显示,需要加入以下配置

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}
配置名 解释 默认值
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 客户端向上游发送数据时将超时多长时间。单位是秒

7、skywalking告警

SkyWalking 告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中。

告警规则的定 义分为两部分:

  1. 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。
  2. Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知

7.1、告警规则

SkyWalking 的发行版都会默认提供config/alarm-settings.yml文件,里面预先定义了一些常用的告警规则。如下:

  • 过去 3 分钟内服务平均响应时间超过 1 秒。
  • 过去 2 分钟服务成功率低于80%。
  • 过去 3 分钟内服务响应时间超过 1s 的百分比
  • 服务实例在过去 2 分钟内平均响应时间超过 1s,并且实例名称与正则表达式匹配。
  • 过去 2 分钟内端点平均响应时间超过 1 秒。
  • 过去 2 分钟内数据库访问平均响应时间超过 1 秒
  • 过去 2 分钟内端点关系平均响应时间超过 1 秒

这些预定义的告警规则,打开config/alarm-settings.yml文件即可看到

告警规则配置项的说明:

  • Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
  • Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script
  • 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:告警消息

7.2、Webhook网路钩子

Webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是 Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件。当该 事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。 SkyWalking的告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,其JSON 数据实基于 List

告警功能实践

1.实体类用来接受数据

@Data
public class SwAlarmDTO {
 private Integer scopeId;
 private String scope;
 private String name;
 private Integer id0;
 private Integer id1;
 private String ruleName;
 private String alarmMessage;
 private Long startTime;
 }

2、接口,用来实现告警通知

@RestController
@RequiredArgsConstructor
@RequestMapping("/alarm")
public class SwAlarmController {
    @PostMapping("/receive")
    public void receive(@RequestBody List<SwAlarmDTO> alarmList) {
        System.out.println(getContent(alarmList));
    }
    private String getContent(List<SwAlarmDTO> alarmList) {
        StringBuilder sb = new StringBuilder();
        for (SwAlarmDTO dto : alarmList) {
            sb.append("scopeId: ").append(dto.getScopeId())
                    .append("\nscope: ").append(dto.getScope())
                    .append("\n目标 Scope 的实体名称: ").append(dto.getName())
                    .append("\nScope 实体的 ID: ").append(dto.getId0())
                    .append("\nid1: ").append(dto.getId1())
                    .append("\n告警规则名称: ").append(dto.getRuleName())
                    .append("\n告警消息内容: ").append(dto.getAlarmMessage())
                    .append("\n告警时间: ").append(dto.getStartTime())
                    .append("\n\n‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐\n\n");
        }
        return sb.toString();
    }
}

3、最后进行配置

config/alarm-settings.yml文件末尾(也就是添加告警后需要请求的接口)

webhooks:
  - http://127.0.0.1:8889/alarm/receive

4、重新启动即可,然后对接口进行请求,尽量触发告警,控制台即可打印出告警信息

目录
相关文章
|
9天前
|
监控 Java 数据安全/隐私保护
性能监控之 JMX 监控 Docker 容器中的 Java 应用
【6月更文挑战9天】性能监控之 JMX 监控 Docker 容器中的 Java 应用
37 1
|
29天前
|
运维 监控 Linux
提升系统稳定性:Linux服务器性能监控与故障排查实践深入理解与实践:持续集成在软件测试中的应用
【5月更文挑战第27天】在互联网服务日益增长的今天,保障Linux服务器的性能和稳定性对于企业运维至关重要。本文将详细探讨Linux服务器性能监控的工具选择、故障排查流程以及优化策略,旨在帮助运维人员快速定位问题并提升系统的整体运行效率。通过实际案例分析,我们将展示如何利用系统资源监控、日志分析和性能调优等手段,有效预防和解决服务器性能瓶颈。
|
1月前
|
Rust 监控 算法
Rust中的系统性能监控与调优:提升应用效能的关键实践
随着Rust在系统级编程中的广泛应用,性能监控与调优变得尤为关键。本文介绍了在Rust中实施系统性能监控的方法,探讨了Rust应用的性能瓶颈,并提供了调优策略与最佳实践,旨在帮助开发者更有效地提升Rust应用的性能。
|
7月前
|
Prometheus 监控 Cloud Native
Prometheus监控Spring Boot应用,自定义应用监控指标
Prometheus监控Spring Boot应用,自定义应用监控指标
138 0
Prometheus监控Spring Boot应用,自定义应用监控指标
|
9月前
|
Web App开发 监控 网络协议
使用 ABAP 事物码 SAT 对从浏览器打开的 SAP应用进行性能监控和测量
使用 ABAP 事物码 SAT 对从浏览器打开的 SAP应用进行性能监控和测量
|
11月前
|
监控
【发电厂】发电厂模型验证应用于电网事件在线性能监测【相量测量单元 (PMU) 数据对电网事件的在线性能监控】研究(Matlab&Simulink实现)
【发电厂】发电厂模型验证应用于电网事件在线性能监测【相量测量单元 (PMU) 数据对电网事件的在线性能监控】研究(Matlab&Simulink实现)
|
Prometheus 监控 Cloud Native
使用Prometheus监控SpringBoot应用
使用Prometheus监控SpringBoot应用
113 0
|
缓存 运维 监控
一文看懂应用性能监控-可能是目前全网最全面的介绍
可观测性的本质是度量基础设施、平台和应用程序,以了解它是如何运行的。与传统监控运维相比,目前主流的监控更加注重发现与预警问题,而可观测性的终极目标是为一个复杂分布式系统所发生的一切给出合理解释。监控更注重软件的交付过程中以及交付后的服务状态,而可观测性则要为全研发与运维的生命周期负责。
1792 0
|
SQL 监控 前端开发
.Net服务器性能监控,应用耗时统一监控平台
系统用于集群的性能监控,应用耗时监控管理,统一日志管理等多维度的性能监控分析。用于监控Windows服务器监控,支持定义插件扩展、Cpu、内存、磁盘读写、网络、iis等性能直播监控,应用好事监控、数据库性能、慢Sql监控、Api监控。
228 0
.Net服务器性能监控,应用耗时统一监控平台
|
监控 NoSQL MongoDB