《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/SkyWalking/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

本文在提供完整代码示例,可见 https://github.com/YunaiV/SpringBoot-Labslab-39 目录。

原创不易,给点个 Star 嘿,一起冲鸭!

1. 概述

如果胖友还没了解过分布式链路追踪 SkyWalking,建议先阅读下艿艿写的 《芋道 SkyWalking 极简入门》 文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 SkyWalking》,哈哈哈。

可能会有胖友会有疑惑,Spring Boot 不是一个单体应用么,为什么可以使用 SkyWalking 进行分布式链路追踪呢?其实这里有一个误区!即使是一个 Spring Boot 单体应用,我们一般可能会和以下服务打交道:

  • 关系数据库,例如说 MySQL、Oracle、SQLServer、PostgreSQL 等等。
  • 文档数据库,例如说 MongoDB 等等。
  • 缓存数据库,例如说 Redis、Memcached 等等。
  • 外部三方服务,例如说微信公众号、微信支付、支付宝支付、短信平台等等。

那么即使是一个 Spring Boot 单体应用,就已经涉及到分布在不同进程中的服务。此时,就已经满足使用 SkyWalking 进行分布式链路追踪的条件,同时也是非常有必要的。例如说,我们线上某个 API 接口访问非常慢,可以通过 SkyWalking 来排查,是因为 MySQL 查询比较慢呢,还是调用的第三方服务比较慢。

在本文中,我们会比《芋道 SkyWalking 极简入门》提供更多在 Spring Boot 中使用的示例。例如说:

  • 对 SpringMVC 的 API 接口的链路追踪
  • 对 JDBC 访问 MySQL 的链路追踪
  • 对 Jedis 访问 Redis 的链路追踪
  • 对 RocketMQ 的消息的发送和消费的链路追踪
  • 等等等等

2. SpringMVC 示例

示例代码对应仓库:lab-39-springmvc

本小节,我们来搭建一个 SkyWalking 对 SpringMVC 的 API 接口的链路追踪。该链路通过如下插件实现收集:

2.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>lab-39-springmvc</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.2 配置文件

application.yml 中,添加服务器端口配置,如下:

server:
port: 8079
  • 设置服务器的端口为 8079 ,避免和 SkyWalking UI 占用的 8080 冲突。

2.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@GetMapping("/echo")
public String echo() {
return "echo";
}

@GetMapping("/hello")
public String hello() {
return "hello";
}

}

2.4 Application

创建 Application.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

2.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 Application#main(String[] args) 方法,启动该 Spring Boot 应用。如果说控制台打印如下日志,说明 SkyWalking Agent 基本加载成功:

# 加载 SkyWalking Agent
DEBUG 2020-01-04 09:42:46:091 main AgentPackagePath : The beacon class location is jar:file:/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class.
INFO 2020-01-04 09:42:46:094 main SnifferConfigInitializer : Config file found in /Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/config/agent.config.

2.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/echo 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 SpringMVC 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

3. 忽略部分 URL 的追踪

示例代码对应仓库:lab-39-springmvc

「2. SpringMVC 示例」小节中,我们已经实现了对 SpringMVC 提供的 HTTP API 接口的链路追踪。但是,我们可能希望忽略部分特殊 URL 的追踪,例如说,健康检查的 HTTP API。

所以,我们可以使用 SkyWalking 提供 trace-ignore-plugin 插件,可以实现忽略部分 URL 的追踪。

本小节,我们无需单独搭建项目,而是直接使用 lab-39-springmvc 项目即可。

3.1 复制插件

trace-ignore-plugin 插件,在 optional-plugins 目录下,是可选插件,所以我们需要复制到 plugins 目录下。命令行操作如下:

# 查看当前所在目录
$ pwd
/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent

# 复制插件到 plugins 目录
$ cp optional-plugins/apm-trace-ignore-plugin-6.6.0.jar plugins/

3.2 配置文件

trace-ignore-plugin 插件,读取 apm-trace-ignore-plugin.config 配置文件,默认情况下不存在,所以我们需要进行创建并配置。命令行操作如下:

# 查看当前所在目录
$ pwd
/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent

# 创建 apm-trace-ignore-plugin.config 配置文件,并进行设置
$ vi config/apm-trace-ignore-plugin.config

配置文件内容如下:

# If the operation name of the first span is matching, this segment should be ignored
# ant path match style
# /path/? Match any single character
# /path/* Match any number of characters
# /path/** Match any number of characters and support multilevel directories
# Multiple path comma separation, like trace.ignore_path=/eureka/**,/consul/**
trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/eureka/**}
  • trace.ignore_path 配置项,设置忽略的 URL 路径,基于 Ant 风格路径表达式
  • 这里,我们配置了读取环境变量 SW_AGENT_TRACE_IGNORE_PATH ,这样方便我们自定义。

3.3 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 Application#main(String[] args) 方法,启动该 Spring Boot 应用。

3.4 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/hello 地址,请求下 Spring Boot 应用提供的 API。

2、然后,查看 SkyWaking Agent 日志,可以看到该 URL 的链路追踪被忽略日志。操作命令如下:

# 查看当前所在目录
$ pwd
/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent

# 查看 SkyWaking Agent 日志,然后搜 TraceIgnoreExtendService 关键字
$ vi logs/skywalking-api.log +
# 日志示例
DEBUG 2020-01-04 13:07:41:720 http-nio-8079-exec-4 TraceIgnoreExtendService : operationName : /demo/hello Ignore tracking

3、之后,在 SkyWalking UI 的查看链路追踪的界面,也看不到该 URL 对应的链路数据。如下图所示:SkyWalking UI 界面 —— 追踪

4. MySQL 示例

示例代码对应仓库:lab-39-mysql

本小节,我们来搭建一个 SkyWalking 对 MySQL 操作的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring JdbcTemplate 进行 MySQL 的操作。对 Spring JdbcTemplate 感兴趣的胖友,可以后续去看看《芋道 Spring Boot JdbcTemplate 入门》文章。

4.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>lab-39-mysql</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 实现对数据库连接池的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency> <!-- 本示例,我们使用 MySQL -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

4.2 配置文件

application.yml 中,添加 MySQL 配置,如下:

server:
port: 8079

spring:
# datasource 数据源配置内容
datasource:
url: jdbc:mysql://127.0.0.1:3306/lab-39-mysql?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password:

这里,胖友记得在测试的数据库中,创建 t_user 表,并插入一条 id = 1 的记录。SQL 脚本如下:

CREATE TABLE `t_user` (
`id` int(8) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(50) NOT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表';

INSERT INTO `t_user`(`id`, `username`, `password`) VALUES (1, 'yudaoyuanma', 'nicai');

4.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private JdbcTemplate template;

@GetMapping("/mysql")
public String mysql() {
this.selectById(1);
return "mysql";
}

public Object selectById(Integer id) {
return template.queryForObject("SELECT id, username, password FROM t_user WHERE id = ?",
new BeanPropertyRowMapper<>(Object.class), // 结果转换成对应的对象。Object 理论来说是 UserDO.class ,这里偷懒了。
id);
}

}
  • /demo/mysql 接口中,会执行一次 MySQL 的查询。

4.4 MySQLApplication

创建 MySQLApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class MySQLApplication {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

4.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 MySQLApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

4.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/mysql 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

接着,点击「Database Dashboard」选项,再点击「Database」选项,可以以数据库为维度的监控数据。如下图所示:SkyWalking UI 界面 —— 仪表盘(Database)

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 MySQL 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

点击红圈的 MySQL 操作的链路数据,可以看到数据的 SQL 语句。如下图所示:SkyWalking UI 界面 —— 追踪(MySQL)

这里,我们暂时无法看到 SQL 的数据参数,可以通过修改 config/agent.config 配置文件,将 plugin.mysql.trace_sql_parameters 配置项,设置为 true 。例如:

# mysql plugin configuration
plugin.mysql.trace_sql_parameters=${SW_MYSQL_TRACE_SQL_PARAMETERS:true}
  • 当然,也可以通过 SW_MYSQL_TRACE_SQL_PARAMETERS 环境变量。

5. Redis 示例

示例代码对应仓库:lab-39-redis

本小节,我们来搭建一个 SkyWalking 对 Redis 操作的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring Data Redis + Jedis 进行 Redis 的操作。对 Spring Data Redis 感兴趣的胖友,可以后续去看看《芋道 Spring Boot Redis 入门》文章。

5.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-redis</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 实现对 Spring Data Redis 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- 引入 Jedis 的依赖,这样 Spring Boot 实现对 Jedis 的自动化配置 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

5.2 配置文件

application.yml 中,添加 Redis 配置,如下:

server:
port: 8079

spring:
# 对应 RedisProperties 类
redis:
host: 127.0.0.1
port: 6379
password: # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
database: 0 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。

5.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private StringRedisTemplate redisTemplate;

@GetMapping("/redis")
public String redis() {
this.get("demo");
return "redis";
}

public void get(String key) {
redisTemplate.opsForValue().get(key);
}

}
  • /demo/redis 接口中,会执行一次 Redis GET 操作。

5.4 RedisApplication

创建 RedisApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class RedisApplication {

public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}

}

5.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 RedisApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

5.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/redis 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 Redis 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

点击红圈的 Redis 操作的链路数据,可以看到 Redis 具体操作。如下图所示:SkyWalking UI 界面 —— 追踪(Redis)

不过没有看到 Redis 操作的具体参数。因为 Spring Data Redis 会把提前具体参数转换成二进制数组,导致 jedis-2.x-plugin 插件的 JedisMethodInterceptor 不进行收集。代码如下:

// JedisMethodInterceptor.java

// String 类型,则进行收集
if (allArguments.length > 0 && allArguments[0] instanceof String) {
Tags.DB_STATEMENT.set(span, method.getName() + " " + allArguments[0]);
// byte[] 类型,则不进行收集
} else if (allArguments.length > 0 && allArguments[0] instanceof byte[]) {
Tags.DB_STATEMENT.set(span, method.getName());
}

6. MongoDB 示例

示例代码对应仓库:lab-39-mongodb

本小节,我们来搭建一个 SkyWalking 对 MongoDB 操作的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring Data MongoDB 进行 MongoDB 的操作。对 Spring Data MongoDB 感兴趣的胖友,可以后续去看看《芋道 Spring Boot MongoDB 入门》文章。

6.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-mongodb</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 自动化配置 Spring Data Mongodb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

6.2 配置文件

application.yml 中,添加 Redis 配置,如下:

server:
port: 8079

spring:
data:
# MongoDB 配置项,对应 MongoProperties 类
mongodb:
host: 127.0.0.1
port: 27017
database: yourdatabase
username: test01
password: password01
# 上述属性,也可以只配置 uri

6.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private MongoTemplate mongoTemplate;

@GetMapping("/mongodb")
public String mysql() {
this.findById(1);
return "mongodb";
}

public UserDO findById(Integer id) {
return mongoTemplate.findOne(new Query(Criteria.where("_id").is(id)), UserDO.class);
}

}
  • /demo/mongodb 接口中,会执行一次 MongoDB 查询操作。
  • UserDO 实体类,直接点击查看。

6.4 MongoDBApplication

创建 MongoDBApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

// Application.java

@SpringBootApplication
public class MongoDBApplication {

public static void main(String[] args) {
SpringApplication.run(MongoDBApplication.class, args);
}

}

6.5 插件配置

默认情况下,SkyWalking Agent MongoDB 插件,不记录操作参数,需要通过配置。命令行操作如下:

# 查看当前所在目录
$ pwd
/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent

# 需改 agent.config 配置文件,并进行设置
$ vi config/agent.config

额外新增如下配置内容如下:

# mongodb plugin configuration
plugin.mongodb.trace_param=${SW_MONGODB_TRACE_PARAM:false}
  • 这样,默认情况下还是保持不记录操作参数,可通过 SW_MONGODB_TRACE_PARAM 环境变量开启。

6.6 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 MongoDBApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

6.7 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/mongodb 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

接着,点击「Database Dashboard」选项,再点击「Database」选项,可以以数据库为维度的监控数据。如下图所示:SkyWalking UI 界面 —— 仪表盘(Database)

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 MongoDB 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

点击红圈的 MongoDB 操作的链路数据,可以看到操作语句。如下图所示:SkyWalking UI 界面 —— 追踪(MySQL)

7. Elasticsearch 示例

示例代码对应仓库:lab-39-elasticsearch-jest

本小节,我们来搭建一个 SkyWalking 对 Elasticsearch 操作的链路追踪。该链路通过如下插件实现收集:

不过略微翻车了。原因是:

  • SkyWalking 6.6.0 版本的 elasticsearch-5.x-plugin 插件,暂时只支持 transport-client 5.2.x-5.6.x 版本。什么意思呢?如果使用 Elasticsearch TCP 协议的客户端,不能使用 6.X 开始的版本。
  • SkyWalking 6.6.0 版本的 elasticsearch-6.x-plugin 插件,暂时只支持 Elasticsearch Rest 协议的客户端。

听起来好像也没啥问题?目前项目中,一般不会直接使用 Elasticsearch 原生的 TCP 协议和 Rest 协议的客户端,而是采用 Spring Data Elasticsearch 库。该库的主流版本是基于 Elasticsearch TCP 协议的客户端,并且使用 transport-client6.X 开始的版本。因此,在我们使用 Spring Data Elasticsearch 主流版本的情况下,SkyWalking 暂时无法实现对 Elasticsearch 的链路追踪。具体艿艿测试的代码示例,可见 lab-39-elasticsearch 仓库。😈 等后面 SkyWalking 提供了支持,艿艿再来更新一波。

不过,目前 Elasticsearch 官方较为推荐采用它提供的 Rest 协议。所以我们也可以采用 Spring Data Jest 库。而 Spring Data Jest 是基于 Jest 之上,对 Spring Data 的实现。Jest 是基于 Elasticsearch Rest 协议的第三方客户端,其内部采用 HttpClient 发起 HTTP 请求。因此,我们可以采用 SkyWalking 的 httpClient-4.x-plugin 插件,间接实现对 Elasticsearch 的链路追踪。咳咳咳 😈

因此,我们最终使用 Spring Data Jest 进行 Elasticsearch 的操作。对 Elasticsearch 感兴趣的胖友,可以后续去看看《芋道 Spring Boot Elasticsearch 入门》文章。

7.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-elasticsearch-jest</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 自动化配置 Spring Data Jest -->
<dependency>
<groupId>com.github.vanroy</groupId>
<artifactId>spring-boot-starter-data-jest</artifactId>
<version>3.3.0.RELEASE</version>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

因为 Spring Data Jest 3.3.0.RELEASE 版本,最高只能支持 Elasticsearch 6.8.4 版本,所以 😭 艿艿又不得不搭建一个 Elasticsearch 6.8.4 版本的服务。心疼自己 5 秒钟,各种倒腾。

7.2 配置文件

application.yml 中,添加 Redis 配置,如下:

server:
port: 8079

spring:
data:
# Jest 配置项
jest:
uri: http://127.0.0.1:9400

7.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private ESUserRepository userRepository;

@GetMapping("/elasticsearch")
public String mysql() {
this.save(1);
this.findById(1);
return "elasticsearch";
}

public void save(Integer id) {
ESUserDO user = new ESUserDO();
user.setId(id);
user.setUsername("username:" + id);
user.setPassword("password:" + id);
user.setCreateTime(new Date());
userRepository.save(user);
}

public ESUserDO findById(Integer id) {
return userRepository.findById(id).orElse(null);
}

}
  • /demo/elasticsearch 接口中,会执行一次 Elasticsearch 插入和查询操作。
  • ESUserDO 实体类,直接点击查看。
  • ESUserRepository ES 数据访问类,直接点击查看。

7.4 ElasticsearchJestApplication

创建 ElasticsearchJestApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication(exclude = {ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})
public class ElasticsearchJestApplication {

public static void main(String[] args) {
SpringApplication.run(ElasticsearchJestApplication.class, args);
}

}

7.5 简单测试

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 ElasticsearchJestApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/elasticsearch 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到特殊的小方块,就是 Elasticsearch 服务。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

点击红圈的使用 HttpClient 发起 HTTP 请求,操作 Elasticsearch 的链路数据。如下图所示:SkyWalking UI 界面 —— 追踪(HttpClient)

不过没有看到 HTTP 请求的具体参数。如果想要的话,胖友需要自行去修改 httpClient-4.x-plugin 插件。不过要注意,因为 HTTP 请求的具体参数可能很长,所以最好做下最大长度的截取。

8. RocketMQ 示例

示例代码对应仓库:lab-39-rocketmq

本小节,我们来搭建一个 SkyWalking 对 RocketMQ 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:

我们将使用 RocketMQ-Spring 进行 RocketMQ 的操作。对 RocketMQ 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 RocketMQ 入门》文章。

考虑到让示例更简单,我们的示例项目包含 RocketMQ 的生产者 Producer 和消费者 Consumer。

8.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-rocketmq</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 实现对 RocketMQ 的自动化配置 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

8.2 配置文件

application.yml 中,添加 RocketMQ 配置,如下:

server:
port: 8079

# rocketmq 配置项,对应 RocketMQProperties 配置类
rocketmq:
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
# Producer 配置项
producer:
group: demo-producer-group # 生产者分组
send-message-timeout: 3000 # 发送消息超时时间,单位:毫秒。默认为 3000 。

8.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoProducer producer;

@GetMapping("/rocketmq")
public String echo() {
this.sendMessage(1);
return "rocketmq";
}

public void sendMessage(Integer id) {
producer.syncSend(id);
}

}
  • /demo/rocketmq 接口中,会执行一次 RocketMQ 发送消息的操作。
  • DemoMessage 消息类,直接点击查看。
  • DemoProducer 生产者类,直接点击查看。
  • DemoConsumer 消费者类,直接点击查看。

8.4 RocketMQApplication

创建 RocketMQApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class RocketMQApplication {

public static void main(String[] args) {
SpringApplication.run(RocketMQApplication.class, args);
}

}

8.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 RocketMQApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

8.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/rocketmq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 RocketMQ 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

注意,可以看到 RocketMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。

点击 RocketMQ Producer 发送消息的链路数据,可以看到 Producer 发送消息的 Topic。如下图所示:SkyWalking UI 界面 —— 追踪(RocketMQ Producer)

点击 RocketMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Topic。如下图所示:SkyWalking UI 界面 —— 追踪(RocketMQ Consumer)

8.7 阿里云的消息队列 ONS 服务

可能部分胖友采用的是阿里云的消息队列 ONS 服务,使用的是 ons-client 库进行 RocketMQ 消息的发送和消费。那么此时,我们就无法使用 SkyWalking 进行 RocketMQ 的链路追踪了。怎么解决呢?

① 方案一,参考 SkyWalking rocketMQ-4.x-plugin 插件的源码,修改成支持 ons-client 库的链路追踪。ons-client 库的代码,和 rocketmq-client 的代码是非常接近的,胖友只要稍微改改就能支持。

② 方案二,阿里云的消息队列 ONS 服务,已经支持 rocketmq-client 进行 RocketMQ 消息的发送和消费。这样,我们就可以继续使用 SkyWalking rocketMQ-4.x-plugin 插件来进行链路追踪。

不过要注意,阿里云消息 ONS 服务大于开源的 RocketMQ 中间件,所以用到 ONS 服务的独有的特性的功能,还是需要使用 ons-client 库。

目前艿艿线上所采用的是方案一,新建了一个 ons-1.x-plugin 插件,实现了对 ONS 服务的链路追踪。

9. Kafka 示例

示例代码对应仓库:lab-39-kafka

本小节,我们来搭建一个 SkyWalking 对 Kafka 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring-Kafka 进行 Kafka 的操作。对 Kafka 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 Kafka 入门》文章。

考虑到让示例更简单,我们的示例项目包含 Kafka 的生产者 Producer 和消费者 Consumer。

9.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-kafka</artifactId>

<dependencies>
<!-- 引入 Spring-Kafka 依赖 -->
<!-- 已经内置 kafka-clients 依赖,所以无需重复引入 -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.2.11.RELEASE</version>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

友情提示: SkyWalking kafka-plugin 对高版本的 kafka-clients 的链路追踪兼容性还存在一点问题,无法追踪到 Kafka Producer 发送消息。

所以,这里我们将 spring-kafka 的版本从 2.3.3.RELEASE 修改成 2.2.11.RELEASE,以使用 kafka-clients 的低版版本 2.0.1

9.2 配置文件

application.yml 中,添加 Kafka 配置,如下:

server:
port: 8079

spring:
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
# Kafka Producer 配置项
producer:
acks: 1 # 0-不应答。1-leader 应答。all-所有 leader 和 follower 应答。
retries: 3 # 发送失败时,重试发送的次数
key-serializer: org.apache.kafka.common.serialization.StringSerializer # 消息的 key 的序列化
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer # 消息的 value 的序列化
# Kafka Consumer 配置项
consumer:
auto-offset-reset: earliest # 设置消费者分组最初的消费进度为 earliest 。可参考博客 https://blog.csdn.net/lishuangzhe7047/article/details/74530417 理解
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring:
json:
trusted:
packages: cn.iocoder.springboot.lab39.skywalkingdemo.message # 消息 POJO 可信目录,解决 JSON 无法反序列化的问题
# Kafka Consumer Listener 监听器配置
listener:
missing-topics-fatal: false # 消费监听接口监听的主题不存在时,默认会报错。所以通过设置为 false ,解决报错

9.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoProducer producer;

@GetMapping("/kafka")
public String echo() throws ExecutionException, InterruptedException {
this.sendMessage(1);
return "kafka";
}

public void sendMessage(Integer id) throws ExecutionException, InterruptedException {
producer.syncSend(id);
}

}
  • /demo/kafka 接口中,会执行一次 Kafka 发送消息的操作。
  • DemoMessage 消息类,直接点击查看。
  • DemoProducer 生产者类,直接点击查看。
  • DemoConsumer 消费者类,直接点击查看。

9.4 KafkaApplication

创建 KafkaApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class KafkaApplication {

public static void main(String[] args) {
SpringApplication.run(KafkaApplication.class, args);
}

}

9.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 KafkaApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

9.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/kafka 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 Kafka 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

注意,可以看到 Kafka 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。

点击 Kafka Producer 发送消息的链路数据,可以看到 Kafka 发送消息的 Topic。如下图所示:SkyWalking UI 界面 —— 追踪(Kafka Producer)

点击 Kafka Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Topic。如下图所示:SkyWalking UI 界面 —— 追踪(Kafka Consumer)

10. RabbitMQ 示例

示例代码对应仓库:lab-39-rabbitmq-demo

本小节,我们来搭建一个 SkyWalking 对 Rabbitmq 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring-AMQP 进行 RabbitMQ 的操作。对 RabbitMQ 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 RabbitMQ 入门》文章。

考虑到让示例更简单,我们的示例项目包含 RabbitMQ 的生产者 Producer 和消费者 Consumer。

10.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-rabbitmq-demo</artifactId>

<dependencies>
<!-- 实现对 RabbitMQ 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

10.2 配置文件

application.yml 中,添加 RabbitMQ 配置,如下:

server:
port: 8079

spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: guest # RabbitMQ 服务的账号
password: guest # RabbitMQ 服务的密码

10.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoProducer producer;

@GetMapping("/rabbitmq")
public String echo() {
this.sendMessage(1);
return "rabbitmq";
}

public void sendMessage(Integer id) {
producer.syncSend(id);
}

}
  • /demo/rabbitmq 接口中,会执行一次 RabbitMQ 发送消息的操作。
  • RabbitConfig 配置类,直接点击查看。
  • DemoMessage 消息类,直接点击查看。
  • DemoProducer 生产者类,直接点击查看。
  • DemoConsumer 消费者类,直接点击查看。

10.4 RabbitMQApplication

创建 RabbitMQApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class RabbitMQApplication {

public static void main(String[] args) {
SpringApplication.run(RabbitMQApplication.class, args);
}

}

10.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 KafkaApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

10.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/rabbitmq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 RabbitMQ 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

注意,可以看到 RabbitMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。

点击 RabbitMQ Producer 发送消息的链路数据,可以看到 RabbitMQ 发送消息的 RoutingKey、Exchange。如下图所示:SkyWalking UI 界面 —— 追踪(RabbitMQ Producer)

点击 RabbitMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 RoutingKey、Exchange、Queue。如下图所示:SkyWalking UI 界面 —— 追踪(RabbitMQ Consumer)

11. ActiveMQ 示例

示例代码对应仓库:lab-39-activemq

本小节,我们来搭建一个 SkyWalking 对 ActiveMQ 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:

我们将使用 Spring-JMS 进行 ActiveMQ 的操作。对 ActiveMQ 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 ActiveMQ 入门》文章。

考虑到让示例更简单,我们的示例项目包含 ActiveMQ 的生产者 Producer 和消费者 Consumer。

11.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-activemq</artifactId>

<dependencies>
<!-- 实现对 ActiveMQ 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

11.2 配置文件

application.yml 中,添加 ActiveMQ 配置,如下:

server:
port: 8079

spring:
# ActiveMQ 配置项,对应 ActiveMQProperties 配置类
activemq:
broker-url: tcp://127.0.0.1:61616 # Activemq Broker 的地址
user: admin # 账号
password: admin # 密码
packages:
trust-all: true # 可信任的反序列化包

11.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoProducer producer;

@GetMapping("/activemq")
public String echo() {
this.sendMessage(1);
return "activemq";
}

public void sendMessage(Integer id) {
producer.syncSend(id);
}

}
  • /demo/activemq 接口中,会执行一次 ActiveMQ 发送消息的操作。
  • DemoMessage 消息类,直接点击查看。
  • DemoProducer 生产者类,直接点击查看。
  • DemoConsumer 消费者类,直接点击查看。

11.4 ActiveMQApplication

创建 ActiveMQApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class ActiveMQApplication {

public static void main(String[] args) {
SpringApplication.run(ActiveMQApplication.class, args);
}

}

11.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 ActiveMQApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

11.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/activemq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 ActiveMQ 小方块。如下图所示:SkyWalking UI 界面 —— 拓扑图

4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

注意,可以看到 ActiveMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。

点击 ActiveMQ Producer 发送消息的链路数据,可以看到 ActiveMQ 发送消息的 Queue。如下图所示:SkyWalking UI 界面 —— 追踪(ActiveMQ Producer)

点击 ActiveMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Queue。如下图所示:SkyWalking UI 界面 —— 追踪(ActiveMQ Consumer)

12. 日志框架示例

示例代码对应仓库:lab-39-logback

在使用 SkyWalking 排查问题的时候,我们可能希望能够跟链路的日志进行关联,那么我们可以将链路编号( SkyWalking TraceId )记录到日志中,从而进行关联。

友情提示:艿艿自己的项目里,在一些业务数据希望跟 SkyWalking 链路进行关联时,会考虑新增一个 traceId 字段,存储 SkyWalking TraceId。例如说:

  • 发送聊天消息时,消息记录上会存储链路编号。
  • 创建交易订单时,订单记录上会存储链路编号。

这样,在排查该数据记录时,我们就可以拿着 traceId 字段,去查响应的链路信息和日志信息。

SkyWalking 提供了多种日志框架的支持,通过不同的插件:

本小节,我们来搭建一个 SLF4J + Logback 日志的 SkyWalking TraceId 的集成示例。对 Logging 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 日志框架 Logging 入门》文章。

12.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>lab-39-logback</artifactId>

<dependencies>
<!-- SkyWalking 对 Logback 的集成 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>6.6.0</version>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

12.2 应用配置文件

application.yml 中,添加配置,如下:

server:
port: 8079

spring:
application:
name: demo-application-logback

12.3 Logback 配置文件

logback-spring.xml 中,添加 Logback 配置,如下:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

<!-- 引入 Spring Boot 默认的 logback XML 配置文件 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

<!-- 控制台 Appender -->
<property name="CONSOLE_LOG_PATTERN" value="%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}"/>
<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>${CONSOLE_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender>

<!-- 从 Spring Boot 配置文件中,读取 spring.application.name 应用名 -->
<springProperty name="applicationName" scope="context" source="spring.application.name" />
<property name="FILE_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } %tid --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 日志文件的路径 -->
<property name="LOG_FILE" value="/Users/yunai/logs/${applicationName}.log"/>
<!-- 日志文件 Appender -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<!--滚动策略,基于时间 + 大小的分包策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 日志的格式化 -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${FILE_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender>

<!-- 设置 Appender -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>

</configuration>

日志配置有点长哈,主要配置 2 处地方,我们来看看图。如下图锁标记:Logback 配置文件

12.4 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

private Logger logger = LoggerFactory.getLogger(getClass());

@GetMapping("/logback")
public String echo() {
logger.info("测试日志");
return "logback";
}

}
  • /demo/logback 接口中,会执行一次日志的记录。

12.5 LogbackApplication

创建 LogbackApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class LogbackApplication {

public static void main(String[] args) {
SpringApplication.run(LogbackApplication.class, args);
}

}

12.6 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 LogbackApplication#main(String[] args) 方法,启动该 Spring Boot 应用。启动日志如下:

// ... 省略其它日志

2020-01-05 21:19:11.420 INFO 18611 TID:N/A --- [ main] c.i.s.l.s.LogbackApplication : Started LogbackApplication in 2.606 seconds (JVM running for 5.456)
  • 因为此时没有 SkyWalking TraceId,所以 %tid 占位符被替换成了 TID:N/A

12.7 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/logback 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。看到日志如下:

2020-01-05 21:21:51.521  INFO 18611 TID:22.37.15782305114330001 --- [nio-8079-exec-1] c.i.s.l.s.controller.DemoController      : 测试日志
  • %tid 占位符被替换成了 SkyWalking TraceId 22.37.15782305114330001

2、然后,可以使用该 SkyWalking TraceId 在 SkyWalking UI 中,进行检索。如下图所示:搜索链路

具体实现原理,感兴趣的胖友,可以看看《SkyWalking 源码分析 —— traceId 集成到日志组件》文章。

13. 自定义追踪方法

示例代码对应仓库:lab-39-trace-annotations

在上述的示例中,我们都是通过 SkyWalking 提供的插件,实现对指定框架的链路追踪。那么,如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,需要怎么做呢?SkyWalking 提供了两种方式:

艿艿在项目中,使用 SkyWalking @Trace 注解较多,所以本小节我们就来看看它的使用示例。

13.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>lab-39-trace-annotations</artifactId>

<dependencies>
<!-- SkyWalking 工具类 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>6.6.0</version>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

13.2 配置文件

application.yml 中,添加配置,如下:

server:
port: 8079

13.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@GetMapping("/trace_annotations")
@Trace(operationName = "trace_annotations")
public String echo() {
// <X> 自定义 SkyWalking Span
ActiveSpan.tag("mp", "芋道源码");

// 返回
return "trace_annotations";
}

}
  • #echo() 方法上,添加了 SkyWalking @Trace 注解,实现 SkyWalking 指定方法的追踪,会创建一个 SkyWalking LocalSpan。同时,可以通过 operationName 属性,设置操作名。

  • <X> 处,通过 ActiveSpan#tag(String key, String value) 方法,设置该 LocalSpan 的标签。ActiveSpan 还有其它方法,如下:

    • ActiveSpan.error() 方法:将当前 Span 标记为出错状态.
    • ActiveSpan.error(String errorMsg) 方法:将当前 Span 标记为出错状态, 并带上错误信息.
    • ActiveSpan.error(Throwable throwable) 方法:将当前 Span 标记为出错状态, 并带上 Throwable。
    • ActiveSpan.debug(String debugMsg) 方法:在当前 Span 添加一个 debug 级别的日志信息.
    • ActiveSpan.info(String infoMsg) 方法:在当前 Span 添加一个 info 级别的日志信息.

另外,我们可以使用 TraceContext#traceId() 方法,获得当前的 SkyWalking TraceId 链路追踪编号。

13.4 TraceAnnotationsApplication

创建 TraceAnnotationsApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class TraceAnnotationsApplication {

public static void main(String[] args) {
SpringApplication.run(TraceAnnotationsApplication.class, args);
}

}

13.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 TraceAnnotationsApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

13.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/trace_annotations 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,查看 SkyWalking UI 链路界面,可以看到我们自定义追踪的方法。示例如下图:自定义链路追踪

点击红圈的 @Trace 注解的链路数据,可以看到具体信息。如下图所示:SkyWalking UI 界面 —— 追踪(@Trace)

具体实现原理,感兴趣的胖友,可以看看《SkyWalking 源码分析 —— @Trace 注解想要追踪的任何方法》文章。

14. OpenTracing 示例

示例代码对应仓库:lab-39-opentracing

在开始本节之前,推荐胖友先阅读下《OpenTracing 官方标准 —— 中文版》规范,对 OpenTracing 有个简单的了解。

opentracing-java 项目中,定义了 OpenTracing Java API。而 SkyWalking apm-toolkit-opentracing 项目,提供了对该 OpenTracing Java API 的实现。因此,我们可以使用它,实现比「13. 自定义追踪方法」小节,更加灵活的自定义追踪,同时可以做到和 SkyWalking 特性无关,毕竟咱使用的是 OpenTracing Java API。

下面,我们来搭建一个 OpenTracing Java API 的使用示例。

14.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-opentracing</artifactId>

<dependencies>
<!-- SkyWalking Opentracing 集成 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-opentracing</artifactId>
<version>6.6.0</version>
</dependency>

<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

14.2 配置文件

application.yml 中,添加配置,如下:

server:
port: 8079

14.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

@GetMapping("/opentracing")
public String echo() {
// <X>创建一个 Span
Tracer tracer = new SkywalkingTracer();
tracer.buildSpan("custom_operation").withTag("mp", "芋道源码").startManual().finish();

// 返回
return "opentracing";
}

}
  • /demo/opentracing 接口中的<X> 处,我们使用 Opentracing Java API 创建了一个 Span。
  • 更多的 Opentracing Java API 的使用,可以看看 opentracing-java 项目提供的示例哈。

14.4 OpentracingApplication

创建 OpentracingApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
public class OpentracingApplication {

public static void main(String[] args) {
SpringApplication.run(OpentracingApplication.class, args);
}

}

14.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 OpentracingApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

14.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/opentracing 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,查看 SkyWalking UI 链路界面,可以看到使用 Opentracing 创建的链路。示例如下图:Opentracing 链路追踪

点击红圈的 Opentracing 创建的链路数据,可以看到具体信息。如下图所示:SkyWalking UI 界面 —— Opentracing

15. Spring 异步任务示例

示例代码对应仓库:lab-39-async

本小节,我们来搭建一个 SkyWalking 对 Spring 异步任务的链路追踪。该链路通过如下插件实现收集:

下面,我们来搭建一个 Spring 异步任务的使用示例。。对 Spring 异步任务感兴趣的胖友,可以后续去看看《芋道 Spring Boot 异步任务入门》文章。

15.1 引入依赖

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<artifactId>lab-39-async</artifactId>

<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

15.2 配置文件

application.yml 中,添加配置,如下:

server:
port: 8079

15.3 DemoController

cn.iocoder.springboot.lab39.skywalkingdemo.controller 包路径下,创建 DemoController 类,提供示例 API 接口。代码如下:

// DemoController.java
@RestController
@RequestMapping("/demo")
public class DemoController {

@Autowired
private DemoService demoService;

@GetMapping("/async")
public String echo() {
demoService.async();
return "async";
}

}

// DemoService.java
@Service
public class DemoService {

@Async
public void async() {
System.out.println("异步任务的执行");
}

}
  • DemoService#async() 方法上,我们添加了 Spring @Async 注解,实现 Spring 异步任务。

15.4 AsyncApplication

创建 AsyncApplication.java 类,配置 @SpringBootApplication 注解即可。代码如下:

@SpringBootApplication
@EnableAsync(proxyTargetClass = true) // 开启 @Async 的支持
public class AsyncApplication {

public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}

}
  • 通过 @EnableAsync 注解,开启 Spring @Async 异步任务的支持。这里,我们设置了 proxyTargetClass = true,使用 CGLIB 实现动态代理,忘记当时踩过什么坑,好像是和 SkyWalking 发生了啥冲突,不太记得了。

15.5 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

然后,执行 OpentracingApplication#main(String[] args) 方法,启动该 Spring Boot 应用。

15.6 简单测试

1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/async 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。

2、然后,查看 SkyWalking UI 链路界面,可以看 Spring 异步任务的链路。示例如下图:Spring 异步任务的链路追踪

另外,如果胖友不想使用 Spring 提供的异步任务的功能,想自己使用线程池实现异步,同时又想实现对该异步任务的链路追踪,可以参考《SkyWalking —— Application-toolkit-trace-cross-thread.md》文档。

16. Dubbo 示例

示例代码对应仓库:

本小节,我们来搭建一个 SkyWalking 对 Dubbo 的远程 RPC 调用的链路追踪。该链路通过如下插件实现收集:

我们来新建一个 lab-39-skywalking-dubbo 模块,一共包含三个子项目。最终如下图所示:项目结构

另外,考虑到目前 Dubbo 主要使用 Zookeeper 作为注册中心,所以本小节也是使用 Zookeeper。不了解的胖友,后续可以看看《Zookeeper 极简入门》文章。

16.1 搭建 API 项目

创建 lab-39-skywalking-dubbo-api 项目,服务接口,定义 Dubbo Service API 接口,提供给消费者使用。

16.1.1 UserService

创建 UserService 接口,定义用户服务 RPC Service 接口。代码如下:

public interface UserService {

/**
* 根据指定用户编号,获得用户信息
*
* @param id 用户编号
* @return 用户信息
*/
String get(Integer id);

}

16.2 搭建服务提供者

创建 skywalking-dubbo-provider 项目,服务提供者,实现 lab-39-skywalking-dubbo-api 项目定义的 Dubbo Service API 接口,提供相应的服务。

16.2.1 引入依赖

创建 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>lab-39-skywalking-dubbo-provider</artifactId>

<dependencies>
<!-- 引入定义的 Dubbo API 接口 -->
<dependency>
<groupId>cn.iocoder.springboot.labs</groupId>
<artifactId>lab-39-skywalking-dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!-- 引入 Spring Boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- 实现对 Dubbo 的自动化配置 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.4.1</version>
</dependency>

<!-- 使用 Zookeeper 作为注册中心 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.13.0</version>
</dependency>
</dependencies>

</project>
  • 具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

16.2.2 配置文件

application.yml 中,添加 Dubbo 配置,如下:

spring:
application:
name: user-service-provider

# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
# Dubbo 应用配置
application:
name: ${spring.application.name} # 应用名
# Dubbo 注册中心配
registry:
address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
# Dubbo 服务提供者协议配置
protocol:
port: -1 # 协议端口。使用 -1 表示随机端口。
name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
# 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者
scan:
base-packages: cn.iocoder.springboot.lab39.skywalkingdemo.providerdemo.service

关于 dubbo 配置项,胖友可以后续阅读《芋道 Spring Boot Dubbo 入门》文章。

16.2.3 UserServiceImpl

创建 UserServiceImpl 类,实现 UserService 接口,用户服务具体实现类。代码如下:

@org.apache.dubbo.config.annotation.Service(version = "1.0.0")
public class UserServiceImpl implements UserService {

@Override
public String get(Integer id) {
return "user:" + id;
}

}

16.2.4 ProviderApplication

创建 ProviderApplication 类,服务提供者的启动类。代码如下:

@SpringBootApplication
public class ProviderApplication {

public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class);
}

}

16.2.5 IDEA 配置项

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

16.3 搭建服务消费者

创建 skywalking-dubbo-consumer 项目,服务消费者,会调用 lab-39-skywalking-dubbo-provider 项目提供的 User Service 服务。

16.3.1 引入依赖

创建 pom.xml 文件中,引入依赖。和「16.2.1 引入依赖」基本是一致的,胖友可以点击 pom.xml 文件查看。

16.3.2 配置文件

application.yml 中,添加 Dubbo 配置,如下:

server:
port: 8079

spring:
application:
name: user-service-consumer

# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
# Dubbo 应用配置
application:
name: ${spring.application.name} # 应用名
# Dubbo 注册中心配置
registry:
address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。

关于 dubbo 配置项,胖友可以后续阅读《芋道 Spring Boot Dubbo 入门》文章。

16.3.3 UserController

创建 UserController 类,提供调用 UserService 服务的 HTTP 接口。代码如下:

@RestController
@RequestMapping("/user")
public class UserController {

@Reference(protocol = "dubbo", version = "1.0.0")
private UserService userService;

@GetMapping("/get")
public String get(@RequestParam("id") Integer id) {
return userService.get(id);
}

}

16.3.4 ConsumerApplication

创建 ConsumerApplication 类,服务消费者的启动类。代码如下:

@SpringBootApplication
public class ConsumerApplication {

public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}

}

16.3.5 IDEA 配置项

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

16.4 简单测试

使用 ProviderApplication 启动服务提供者,使用 ConsumerApplication 启动服务消费者。

① 首先,使用浏览器,访问 http://127.0.0.1:8079/user/get?id=1 地址,使用 Dubbo 调用 user-service-provider 服务。因为,我们要追踪下该链路。

② 然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:SkyWalking UI 界面 —— 仪表盘

③ 之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到两个服务的小方块,以及对应的调用关系。如下图所示:SkyWalking UI 界面 —— 拓扑图

④ 再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:SkyWalking UI 界面 —— 追踪

17. 抽样收集示例

示例代码对应仓库:lab-39-springmvc

在访问量较少时,链路全量收集不会对系统带来多少负担,同时能够完整的观测到系统的运行状况。但是在访问量较大时,全量的链路收集,对链路收集的客户端(应用)、服务端(例如说 SkyWalking OAP Collector)、存储器(例如说 Elastcsearch)都会带来较大的性能开销,甚至会影响应用的正常运行。

因此,在访问量级较大的情况下,我们往往会选择抽样采样,只选择收集部分链路信息。SkyWalking Agent 在 agent/config/agent.config 配置文件中,定义了 agent.sample_n_per_3_secs 配置项,设置每 3 秒可收集的链路数据的数量

Negative or zero means off, by default.SAMPLE_N_PER_3_SECS means sampling N TraceSegment in 3 seconds tops.

  • 默认配置下,不进行限制,即获取全部链路数据。

友情提示:哈哈哈~如果访问量不是特别大,建议还是全量收集!

本小节,我们无需单独搭建项目,而是直接使用 lab-39-springmvc 项目即可。

17.1 SkyWalking Agent 配置文件

修改 SkyWalking Agent 的 agent/config/agent.config 配置文件,开放 agent.sample_n_per_3_secs 配置项,支持使用 SW_AGENT_SAMPLE 环境变量。命令行操作如下:

# 查看当前所在目录
$ pwd
/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent

# 创建 apm-trace-ignore-plugin.config 配置文件,并进行设置
$ vi config/apm-trace-ignore-plugin.config

配置文件内容如下:

# The number of sampled traces per 3 seconds
# Negative number means sample traces as many as possible, most likely 100%
# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1}

这样,每个项目可以通过 SW_AGENT_SAMPLE 环境变量,可以实现自定义抽样收集数量。

17.2 IDEA 配置

通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:Run/Debug Configurations

通过设置 SW_AGENT_SAMPLE 环境变量为 1,实现每 3 秒只收集一个链路数据,方便演示测试。

17.3 简单测试

① 首先,使用浏览器,疯狂访问下 http://127.0.0.1:8079/demo/echo 地址,请求下 Spring Boot 应用提供的 API。

② 之后,在 SkyWalking UI 的查看链路追踪的界面,看到只有部分链路被收集。😈 这里暂时就不贴图了,嘿嘿~

666. 彩蛋

发现给自己挖了一个深坑,竟然硬生生在一个周末,把主流框架的示例,一个一个搭建处理,并进行测试。😈 现在已经是周一的凌晨 00:22 ,我太难了~

有一点要注意,SkyWalking Agent 提供的插件,是基于我们使用的框架的方法,通过 AOP 的方式进行追踪,所以可能存在不兼容的情况,毕竟框架的代码在不断迭代,方法可能存在一定的变更。因此,一定要注意查看《SkyWalking —— Supported-list.md》文档。

当然,文档罗列的是 SkyWalking 开发团队已经测试过,经过确认支持的框架的版本。具体的,胖友最好动手测试下,自己再验证一波。如果碰到不支持的情况,可以查看对应框架的 SkyWalking 插件代码,比较容易就能定位到源码落。

嘻嘻,想要对 SkyWalking 做进一步深入的胖友,欢迎来看艿艿写的《SkyWalking 源码解析》。美滋滋~

文章目录
  1. 1. 1. 概述
  2. 2. 2. SpringMVC 示例
    1. 2.1. 2.1 引入依赖
    2. 2.2. 2.2 配置文件
    3. 2.3. 2.3 DemoController
    4. 2.4. 2.4 Application
    5. 2.5. 2.5 IDEA 配置
    6. 2.6. 2.6 简单测试
  3. 3. 3. 忽略部分 URL 的追踪
    1. 3.1. 3.1 复制插件
    2. 3.2. 3.2 配置文件
    3. 3.3. 3.3 IDEA 配置
    4. 3.4. 3.4 简单测试
  4. 4. 4. MySQL 示例
    1. 4.1. 4.1 引入依赖
    2. 4.2. 4.2 配置文件
    3. 4.3. 4.3 DemoController
    4. 4.4. 4.4 MySQLApplication
    5. 4.5. 4.5 IDEA 配置
    6. 4.6. 4.6 简单测试
  5. 5. 5. Redis 示例
    1. 5.1. 5.1 引入依赖
    2. 5.2. 5.2 配置文件
    3. 5.3. 5.3 DemoController
    4. 5.4. 5.4 RedisApplication
    5. 5.5. 5.5 IDEA 配置
    6. 5.6. 5.6 简单测试
  6. 6. 6. MongoDB 示例
    1. 6.1. 6.1 引入依赖
    2. 6.2. 6.2 配置文件
    3. 6.3. 6.3 DemoController
    4. 6.4. 6.4 MongoDBApplication
    5. 6.5. 6.5 插件配置
    6. 6.6. 6.6 IDEA 配置
    7. 6.7. 6.7 简单测试
  7. 7. 7. Elasticsearch 示例
    1. 7.1. 7.1 引入依赖
    2. 7.2. 7.2 配置文件
    3. 7.3. 7.3 DemoController
    4. 7.4. 7.4 ElasticsearchJestApplication
    5. 7.5. 7.5 简单测试
  8. 8. 8. RocketMQ 示例
    1. 8.1. 8.1 引入依赖
    2. 8.2. 8.2 配置文件
    3. 8.3. 8.3 DemoController
    4. 8.4. 8.4 RocketMQApplication
    5. 8.5. 8.5 IDEA 配置
    6. 8.6. 8.6 简单测试
    7. 8.7. 8.7 阿里云的消息队列 ONS 服务
  9. 9. 9. Kafka 示例
    1. 9.1. 9.1 引入依赖
    2. 9.2. 9.2 配置文件
    3. 9.3. 9.3 DemoController
    4. 9.4. 9.4 KafkaApplication
    5. 9.5. 9.5 IDEA 配置
    6. 9.6. 9.6 简单测试
  10. 10. 10. RabbitMQ 示例
    1. 10.1. 10.1 引入依赖
    2. 10.2. 10.2 配置文件
    3. 10.3. 10.3 DemoController
    4. 10.4. 10.4 RabbitMQApplication
    5. 10.5. 10.5 IDEA 配置
    6. 10.6. 10.6 简单测试
  11. 11. 11. ActiveMQ 示例
    1. 11.1. 11.1 引入依赖
    2. 11.2. 11.2 配置文件
    3. 11.3. 11.3 DemoController
    4. 11.4. 11.4 ActiveMQApplication
    5. 11.5. 11.5 IDEA 配置
    6. 11.6. 11.6 简单测试
  12. 12. 12. 日志框架示例
    1. 12.1. 12.1 引入依赖
    2. 12.2. 12.2 应用配置文件
    3. 12.3. 12.3 Logback 配置文件
    4. 12.4. 12.4 DemoController
    5. 12.5. 12.5 LogbackApplication
    6. 12.6. 12.6 IDEA 配置
    7. 12.7. 12.7 简单测试
  13. 13. 13. 自定义追踪方法
    1. 13.1. 13.1 引入依赖
    2. 13.2. 13.2 配置文件
    3. 13.3. 13.3 DemoController
    4. 13.4. 13.4 TraceAnnotationsApplication
    5. 13.5. 13.5 IDEA 配置
    6. 13.6. 13.6 简单测试
  14. 14. 14. OpenTracing 示例
    1. 14.1. 14.1 引入依赖
    2. 14.2. 14.2 配置文件
    3. 14.3. 14.3 DemoController
    4. 14.4. 14.4 OpentracingApplication
    5. 14.5. 14.5 IDEA 配置
    6. 14.6. 14.6 简单测试
  15. 15. 15. Spring 异步任务示例
    1. 15.1. 15.1 引入依赖
    2. 15.2. 15.2 配置文件
    3. 15.3. 15.3 DemoController
    4. 15.4. 15.4 AsyncApplication
    5. 15.5. 15.5 IDEA 配置
    6. 15.6. 15.6 简单测试
  16. 16. 16. Dubbo 示例
    1. 16.1. 16.1 搭建 API 项目
      1. 16.1.1. 16.1.1 UserService
    2. 16.2. 16.2 搭建服务提供者
      1. 16.2.1. 16.2.1 引入依赖
      2. 16.2.2. 16.2.2 配置文件
      3. 16.2.3. 16.2.3 UserServiceImpl
      4. 16.2.4. 16.2.4 ProviderApplication
      5. 16.2.5. 16.2.5 IDEA 配置项
    3. 16.3. 16.3 搭建服务消费者
      1. 16.3.1. 16.3.1 引入依赖
      2. 16.3.2. 16.3.2 配置文件
      3. 16.3.3. 16.3.3 UserController
      4. 16.3.4. 16.3.4 ConsumerApplication
      5. 16.3.5. 16.3.5 IDEA 配置项
    4. 16.4. 16.4 简单测试
  17. 17. 17. 抽样收集示例
    1. 17.1. 17.1 SkyWalking Agent 配置文件
    2. 17.2. 17.2 IDEA 配置
    3. 17.3. 17.3 简单测试
  18. 18. 666. 彩蛋