Spring Cloud Alibaba系列(二)微服务监控组件Skywalking的简单使用
SkyWalking是分布式链路调用服务监控组件,微服务上线后,需要监控运行指标,比如系统的吞吐量,服务响应时间,CPU内存暂用率,异常等信息,它通过Agent收集日志,可以把数据存储在ES,MySQL等介质中,
下面来说说简单的使用。
一. 搭建Skywalking运行环境
使用https://www.apache.org/dyn/closer.cgi/skywalking/9.4.0/apache-skywalking-apm-9.4.0.tar.gz下载安装包
解压,进入webapp目录,打开application.yml
修改工作端口为18081,避免端口冲突
serverPort: ${SW_SERVER_PORT:-18081}
再进入config目录,打开application.yml,修改存储介质为MySQL,以mysql为例
storage:
selector: ${SW_STORAGE:mysql}
修改MySQL具体配置信息
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest?rewriteBatchedStatements=true&serverTimezone=UTC"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:password}
dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
maxSizeOfBatchSql: ${SW_STORAGE_MAX_SIZE_OF_BATCH_SQL:2000}
asyncBatchPersistentPoolSize: ${SW_STORAGE_ASYNC_BATCH_PERSISTENT_POOL_SIZE:4}
在MySQL中创建swtest库
在oap-libs中上传mysql驱动
进入bin目录运行startup.bat,启动后在浏览器打开链接http://localhost:18081/
可以看到,在mysql里已经自动创建了很多表
二. 整合Skywalking
下载Skywalking探针,在以下链接下载https://www.apache.org/dyn/closer.cgi/skywalking/java-agent/8.14.0/apache-skywalking-java-agent-8.14.0.tgz
解压后待使用,我的目录是:H:\apache-skywalking-java-agent-8.14.0\skywalking-agent\skywalking-agent.jar
在项目启动命令中添加如下参数配置
-javaagent:H:\apache-skywalking-java-agent-8.14.0\skywalking-agent\skywalking-agent.jar -Dskywalking.agent.service_name=customer -Dskywalking.collector.backend_service=localhost:11800
多次重复刷新接口,发现在控制台页面出现了服务监控数据
点击具体服务,点击服务名称customer,可以查看详情
为此Skywalking安装配置成功,服务运行状态采集成功。
三. 简单的链路监控
首先准备以下四个服务
项目名 | 说明 |
providerForAB | 端口9900 |
providerA | 端口8181 |
providerB | 端口8182 |
customer | 端口8999 |
四个项目的pom.xml配置成一样,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--skywalking traceId 记录到logback日志-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
需要说明的是,providerA和providerB两个项目不同的地方是端口号,由于在本机上避免端口冲突,而正式环境都是部署在不同机器上的,这是同一个服务的不同节点,不需要对端口号进行区分
providerA的配置文件如下:
server: port: 8181 servlet: session: timeout: 1800 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: serviceProvider
providerB的配置文件如下:
server: port: 8182 servlet: session: timeout: 1800 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: serviceProvider
customer的配置文件如下:
server: port: 8999 servlet: session: timeout: 1800 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: customer
providerForAB的配置文件如下:
server: port: 9900 servlet: session: timeout: 1800 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: providerForAB
在四个项目中的resource目录都添加logback-spring.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <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.TraceIdPatternLogbackLayout"> <pattern>%d{HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n</pattern> </layout> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT"/> </root> </configuration>
大家注意到[%tid]就是用来标识同一个请求的,四个服务启动后,控制台输出的tid都是N/A
在四个项目的启动参数都加上以下代码,其中skywalking.agent.service_name配置成具体的服务名,这里以customer服务为例:
-javaagent:H:\apache-skywalking-java-agent-8.14.0\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=customer
-Dskywalking.collector.backend_service=localhost:11800
多次访问http://localhost:8999/customerCall接口,此接口就是customer服务的接口,发现各个项目控制台中打印的tid是一致的,以下是从不同项目的摘出来的内容:
11:51:04.501 [TID:a652d39f60f147d2a3eb5277bb0a47b2.92.16795434645000001] [http-nio-8999-exec-5] INFO c.e.spingbootlearn.controller.Demo - customer节点访问A或B节点 11:51:05.000 [TID:a652d39f60f147d2a3eb5277bb0a47b2.92.16795434645000001] [http-nio-8182-exec-9] INFO c.e.spingbootlearn.controller.Demo - 通过B节点访问业务接口 11:51:06.052 [TID:a652d39f60f147d2a3eb5277bb0a47b2.92.16795434645000001] [http-nio-9900-exec-2] INFO c.e.spingbootlearn.controller.Demo - providerForAB业务接口返回数据
进入Skywalking控制台界面,切换到trace标签页,可以看到请求在整个链路的处理流程,输入tid:a652d39f60f147d2a3eb5277bb0a47b2.92.16795434645000001
这样我们就可以进行简单的链路追踪,查看经过节点的耗时,进行进一步排查。
四. 告警规则和告警信息发送
通过前文,我们基本把简单使用流程通过小例子演示完了,接下来看看如果得到告警反馈。
打开SkyWalking的APM文件目录,进入config目录,打开alarm-settings.yml,这个文件就是大部分默认的监控规则,我们只需改改参数即可使用
下面我们改下红框里面的规则,原来10分钟内,请求响应时间超过1000毫秒3次以上报警,我们改成超过1毫秒且大于1次就报警,如下:
service_resp_time_rule: metrics-name: service_resp_time op: ">" threshold: 1 period: 10 count: 1 silence-period: 5
重启Skywalking,在控制台告警页面可以看到告警信息了
下面我们通过webhooks接收告警信息,后续可以在应用里处理信息发送短信息或email
首先创建告警信息类接收告警信息
public class AlermMsg { private int scopeId; private String name; private String id0; private String id1; private String alarmMessage; private long startTime; public int getScopeId() { return scopeId; } public void setScopeId(int scopeId) { this.scopeId = scopeId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId0() { return id0; } public void setId0(String id0) { this.id0 = id0; } public String getId1() { return id1; } public void setId1(String id1) { this.id1 = id1; } public String getAlarmMessage() { return alarmMessage; } public void setAlarmMessage(String alarmMessage) { this.alarmMessage = alarmMessage; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } }
在customer项目创建接收接口
@PostMapping("/notify") public void notify(@RequestBody List<AlermMsg> msgs) { logger.error("接收到告警信息,开始处理,可以在此发送短信息或邮件通知"); for (AlermMsg msg : msgs) { logger.error("告警时间:" + msg.getStartTime() + "告警消息:" + msg.getAlarmMessage()); } }
修改alarm-settings.yml中的webhooks
webhooks: - http://127.0.0.1:8999/notify
如下图所示,我们的接口已经接收到告警信息推送
至此,整篇Skywalking对微服务的监控的初步集成的使用讲解结束。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?