文章40 | 阅读 30616 | 点赞0
如果胖友还没了解过分布式链路追踪 SkyWalking,建议先阅读下艿艿写的 《SkyWalking 极简入门》 文章。虽然这篇文章标题是安装部署,实际可以理解成《一文带你快速入门 SkyWalking》,哈哈哈。
可能会有胖友会有疑惑,Spring Boot 不是一个单体应用么,为什么可以使用 SkyWalking 进行分布式链路追踪呢?其实这里有一个误区!即使是一个 Spring Boot 单体应用,我们一般可能会和以下服务打交道:
那么即使是一个 Spring Boot 单体应用,就已经涉及到分布在不同进程中的服务。此时,就已经满足使用 SkyWalking 进行分布式链路追踪的条件,同时也是非常有必要的。例如说,我们线上某个 API 接口访问非常慢,可以通过 SkyWalking 来排查,是因为 MySQL 查询比较慢呢,还是调用的第三方服务比较慢。
在本文中,我们会比《SkyWalking 极简入门》提供更多在 Spring Boot 中使用的示例。例如说:
示例代码对应仓库:lab-39-springmvc。
本小节,我们来搭建一个 SkyWalking 对 SpringMVC 的 API 接口的链路追踪。该链路通过如下插件实现收集:
在 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>
在 application.yml
中,添加服务器端口配置,如下:
server:
port: 8079
在 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";
}
}
创建 Application.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 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.
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/echo 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 SpringMVC 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
示例代码对应仓库:lab-39-springmvc 。
在「2. SpringMVC 示例」小节中,我们已经实现了对 SpringMVC 提供的 HTTP API 接口的链路追踪。但是,我们可能希望忽略部分特殊 URL 的追踪,例如说,健康检查的 HTTP API。
所以,我们可以使用 SkyWalking 提供 trace-ignore-plugin
插件,可以实现忽略部分 URL 的追踪。
本小节,我们无需单独搭建项目,而是直接使用 lab-39-springmvc 项目即可。
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/
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
,这样方便我们自定义。通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 Application#main(String[] args)
方法,启动该 Spring Boot 应用。
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 对应的链路数据。如下图所示:
示例代码对应仓库:lab-39-mysql。
本小节,我们来搭建一个 SkyWalking 对 MySQL 操作的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring JdbcTemplate 进行 MySQL 的操作。对 Spring JdbcTemplate 感兴趣的胖友,可以后续去看看《芋道 Spring Boot JdbcTemplate 入门》文章。
在 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>
在 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');
在 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 的查询。创建 MySQLApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class MySQLApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 MySQLApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/mysql 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
接着,点击「Database Dashboard」选项,再点击「Database」选项,可以以数据库为维度的监控数据。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 MySQL 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
点击红圈的 MySQL 操作的链路数据,可以看到数据的 SQL 语句。如下图所示:
这里,我们暂时无法看到 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
环境变量。示例代码对应仓库:lab-39-redis。
本小节,我们来搭建一个 SkyWalking 对 Redis 操作的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring Data Redis + Jedis 进行 Redis 的操作。对 Spring Data Redis 感兴趣的胖友,可以后续去看看《Spring Boot Redis 入门》文章。
在 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>
在 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 ,表示不限制。
在 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 操作。创建 RedisApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 RedisApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/redis 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 Redis 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
点击红圈的 Redis 操作的链路数据,可以看到 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());
}
示例代码对应仓库:lab-39-mongodb。
本小节,我们来搭建一个 SkyWalking 对 MongoDB 操作的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring Data MongoDB 进行 MongoDB 的操作。对 Spring Data MongoDB 感兴趣的胖友,可以后续去看看《Spring Boot MongoDB 入门》文章。
在 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>
在 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
在 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 查询操作。创建 MongoDBApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
// Application.java
@SpringBootApplication
public class MongoDBApplication {
public static void main(String[] args) {
SpringApplication.run(MongoDBApplication.class, args);
}
}
默认情况下,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
环境变量开启。通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 MongoDBApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/mongodb 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
接着,点击「Database Dashboard」选项,再点击「Database」选项,可以以数据库为维度的监控数据。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 MongoDB 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
点击红圈的 MongoDB 操作的链路数据,可以看到操作语句。如下图所示:
示例代码对应仓库:lab-39-elasticsearch-jest。
本小节,我们来搭建一个 SkyWalking 对 Elasticsearch 操作的链路追踪。该链路通过如下插件实现收集:
不过略微翻车了。原因是:
6.6.0
版本的 elasticsearch-5.x-plugin
插件,暂时只支持 transport-client
5.2.x
-5.6.x
版本。什么意思呢?如果使用 Elasticsearch TCP 协议的客户端,不能使用 6.X
开始的版本。6.6.0
版本的 elasticsearch-6.x-plugin
插件,暂时只支持 Elasticsearch Rest 协议的客户端。听起来好像也没啥问题?目前项目中,一般不会直接使用 Elasticsearch 原生的 TCP 协议和 Rest 协议的客户端,而是采用 Spring Data Elasticsearch 库。该库的主流版本是基于 Elasticsearch TCP 协议的客户端,并且使用 transport-client
的 6.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 入门》文章。
在 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 秒钟,各种倒腾。
在 application.yml
中,添加 Redis 配置,如下:
server:
port: 8079
spring:
data:
# Jest 配置项
jest:
uri: http://127.0.0.1:9400
在 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 插入和查询操作。创建 ElasticsearchJestApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication(exclude = {ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})
public class ElasticsearchJestApplication {
public static void main(String[] args) {
SpringApplication.run(ElasticsearchJestApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 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 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到特殊的小方块,就是 Elasticsearch 服务。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
点击红圈的使用 HttpClient 发起 HTTP 请求,操作 Elasticsearch 的链路数据。如下图所示:
不过没有看到 HTTP 请求的具体参数。如果想要的话,胖友需要自行去修改 httpClient-4.x-plugin
插件。不过要注意,因为 HTTP 请求的具体参数可能很长,所以最好做下最大长度的截取。
示例代码对应仓库:lab-39-rocketmq。
本小节,我们来搭建一个 SkyWalking 对 RocketMQ 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:
我们将使用 RocketMQ-Spring 进行 RocketMQ 的操作。对 RocketMQ 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 RocketMQ 入门》文章。
考虑到让示例更简单,我们的示例项目包含 RocketMQ 的生产者 Producer 和消费者 Consumer。
在 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>
在 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 。
在 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 发送消息的操作。创建 RocketMQApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class RocketMQApplication {
public static void main(String[] args) {
SpringApplication.run(RocketMQApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 RocketMQApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/rocketmq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 RocketMQ 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
注意,可以看到 RocketMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。
点击 RocketMQ Producer 发送消息的链路数据,可以看到 Producer 发送消息的 Topic。如下图所示:
点击 RocketMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Topic。如下图所示:
可能部分胖友采用的是阿里云的消息队列 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 服务的链路追踪。
示例代码对应仓库:lab-39-kafka。
本小节,我们来搭建一个 SkyWalking 对 Kafka 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring-Kafka 进行 Kafka 的操作。对 Kafka 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 Kafka 入门》文章。
考虑到让示例更简单,我们的示例项目包含 Kafka 的生产者 Producer 和消费者 Consumer。
在 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>
kafka-plugin
对高版本的 kafka-clients
的链路追踪兼容性还存在一点问题,无法追踪到 Kafka Producer 发送消息。所以,这里我们将 spring-kafka
的版本从 2.3.3.RELEASE
修改成 2.2.11.RELEASE
,以使用 kafka-clients
的低版版本 2.0.1
。
在 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 ,解决报错
在 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 发送消息的操作。创建 KafkaApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class KafkaApplication {
public static void main(String[] args) {
SpringApplication.run(KafkaApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 KafkaApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/kafka 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 Kafka 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
注意,可以看到 Kafka 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。
点击 Kafka Producer 发送消息的链路数据,可以看到 Kafka 发送消息的 Topic。如下图所示:
点击 Kafka Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Topic。如下图所示:
示例代码对应仓库:lab-39-rabbitmq-demo。
本小节,我们来搭建一个 SkyWalking 对 Rabbitmq 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring-AMQP 进行 RabbitMQ 的操作。对 RabbitMQ 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 消息队列 RabbitMQ 入门》文章。
考虑到让示例更简单,我们的示例项目包含 RabbitMQ 的生产者 Producer 和消费者 Consumer。
在 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>
在 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 服务的密码
在 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 发送消息的操作。创建 RabbitMQApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class RabbitMQApplication {
public static void main(String[] args) {
SpringApplication.run(RabbitMQApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 KafkaApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/rabbitmq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 RabbitMQ 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
注意,可以看到 RabbitMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。
点击 RabbitMQ Producer 发送消息的链路数据,可以看到 RabbitMQ 发送消息的 RoutingKey、Exchange。如下图所示:
点击 RabbitMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 RoutingKey、Exchange、Queue。如下图所示:
示例代码对应仓库:lab-39-activemq。
本小节,我们来搭建一个 SkyWalking 对 ActiveMQ 消息的发送和消费的链路追踪。该链路通过如下插件实现收集:
我们将使用 Spring-JMS 进行 ActiveMQ 的操作。对 ActiveMQ 感兴趣的胖友,可以后续去看看《Spring Boot 消息队列 ActiveMQ 入门》文章。
考虑到让示例更简单,我们的示例项目包含 ActiveMQ 的生产者 Producer 和消费者 Consumer。
在 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>
在 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 # 可信任的反序列化包
在 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 发送消息的操作。创建 ActiveMQApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class ActiveMQApplication {
public static void main(String[] args) {
SpringApplication.run(ActiveMQApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 ActiveMQApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/activemq 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
3、之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到 ActiveMQ 小方块。如下图所示:
4、再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
注意,可以看到 ActiveMQ 消息的发送,到该消息的异步的消费,都被串联在一个整体链路中。这样对我们日常排查问题,会非常便捷舒服。
点击 ActiveMQ Producer 发送消息的链路数据,可以看到 ActiveMQ 发送消息的 Queue。如下图所示:
点击 ActiveMQ Consumer 消费消息的链路数据,可以看到 Consumer 消费消息的 Queue。如下图所示:
示例代码对应仓库:lab-39-logback。
在使用 SkyWalking 排查问题的时候,我们可能希望能够跟链路的日志进行关联,那么我们可以将链路编号( SkyWalking TraceId )记录到日志中,从而进行关联。
友情提示:艿艿自己的项目里,在一些业务数据希望跟 SkyWalking 链路进行关联时,会考虑新增一个 traceId
字段,存储 SkyWalking TraceId。例如说:
这样,在排查该数据记录时,我们就可以拿着 traceId
字段,去查响应的链路信息和日志信息。
SkyWalking 提供了多种日志框架的支持,通过不同的插件:
apm-toolkit-log4j-1.x-activation
:支持 Log4j1 日志框架,对应《Application-toolkit-log4j-1.x.md》文档。apm-toolkit-log4j-2.x-activation
:支持 Log4j2 日志框架,对应《Application-toolkit-log4j-2.x.md》文档。apm-toolkit-logback-1.x-activation
:支持 Logback 日志框架,对应《Application-toolkit-logback-1.x.md》文档。本小节,我们来搭建一个 SLF4J + Logback 日志的 SkyWalking TraceId 的集成示例。对 Logging 感兴趣的胖友,可以后续去看看《芋道 Spring Boot 日志框架 Logging 入门》文章。
在 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>
在 application.yml
中,添加配置,如下:
server:
port: 8079
spring:
application:
name: demo-application-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 处地方,我们来看看图。如下图锁标记:
在 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
接口中,会执行一次日志的记录。创建 LogbackApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class LogbackApplication {
public static void main(String[] args) {
SpringApplication.run(LogbackApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 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)
%tid
占位符被替换成了 TID:N/A
。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 集成到日志组件》文章。
示例代码对应仓库:lab-39-trace-annotations。
在上述的示例中,我们都是通过 SkyWalking 提供的插件,实现对指定框架的链路追踪。那么,如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,需要怎么做呢?SkyWalking 提供了两种方式:
@Trace
注解,可见《Application-toolkit-trace.md》文档。<enhanced />
配置,可见《Customize-enhance-trace.md》文档。艿艿在项目中,使用 SkyWalking @Trace
注解较多,所以本小节我们就来看看它的使用示例。
在 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>
在 application.yml
中,添加配置,如下:
server:
port: 8079
在 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 链路追踪编号。
创建 TraceAnnotationsApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下:
@SpringBootApplication
public class TraceAnnotationsApplication {
public static void main(String[] args) {
SpringApplication.run(TraceAnnotationsApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 TraceAnnotationsApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/trace_annotations 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,查看 SkyWalking UI 链路界面,可以看到我们自定义追踪的方法。示例如下图:
点击红圈的 @Trace
注解的链路数据,可以看到具体信息。如下图所示:
具体实现原理,感兴趣的胖友,可以看看《SkyWalking 源码分析 —— @Trace 注解想要追踪的任何方法》文章。
示例代码对应仓库: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 的使用示例。
在 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>
在 application.yml
中,添加配置,如下:
server:
port: 8079
在 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。创建 OpentracingApplication.java
类,配置 @SpringBootApplication
注解即可。代码如下
@SpringBootApplication
public class OpentracingApplication {
public static void main(String[] args) {
SpringApplication.run(OpentracingApplication.class, args);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 OpentracingApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/opentracing 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,查看 SkyWalking UI 链路界面,可以看到使用 Opentracing 创建的链路。示例如下图:
点击红圈的 Opentracing 创建的链路数据,可以看到具体信息。如下图所示:
示例代码对应仓库:lab-39-async。
本小节,我们来搭建一个 SkyWalking 对 Spring 异步任务的链路追踪。该链路通过如下插件实现收集:
下面,我们来搭建一个 Spring 异步任务的使用示例。。对 Spring 异步任务感兴趣的胖友,可以后续去看看《芋道 Spring Boot 异步任务入门》文章。
在 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>
在 application.yml
中,添加配置,如下:
server:
port: 8079
在 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 异步任务。创建 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 发生了啥冲突,不太记得了。通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
然后,执行 OpentracingApplication#main(String[] args)
方法,启动该 Spring Boot 应用。
1、首先,使用浏览器,访问下 http://127.0.0.1:8079/demo/async 地址,请求下 Spring Boot 应用提供的 API。因为,我们要追踪下该链路。
2、然后,查看 SkyWalking UI 链路界面,可以看 Spring 异步任务的链路。示例如下图:
另外,如果胖友不想使用 Spring 提供的异步任务的功能,想自己使用线程池实现异步,同时又想实现对该异步任务的链路追踪,可以参考《SkyWalking —— Application-toolkit-trace-cross-thread.md》文档。
示例代码对应仓库:
lab-39-skywalking-dubbo-api
skywalking-dubbo-provider
skywalking-dubbo-consumer
本小节,我们来搭建一个 SkyWalking 对 Dubbo 的远程 RPC 调用的链路追踪。该链路通过如下插件实现收集:
我们来新建一个 lab-39-skywalking-dubbo
模块,一共包含三个子项目。最终如下图所示:
另外,考虑到目前 Dubbo 主要使用 Zookeeper 作为注册中心,所以本小节也是使用 Zookeeper。不了解的胖友,后续可以看看《Zookeeper 极简入门》文章。
创建 lab-39-skywalking-dubbo-api
项目,服务接口,定义 Dubbo Service API 接口,提供给消费者使用。
创建 UserService 接口,定义用户服务 RPC Service 接口。代码如下:
public interface UserService {
/**
* 根据指定用户编号,获得用户信息
*
* @param id 用户编号
* @return 用户信息
*/
String get(Integer id);
}
创建 skywalking-dubbo-provider
项目,服务提供者,实现 lab-39-skywalking-dubbo-api
项目定义的 Dubbo Service API 接口,提供相应的服务。
创建 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>
在 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 入门》文章。
创建 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;
}
}
创建 ProviderApplication 类,服务提供者的启动类。代码如下:
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
创建 skywalking-dubbo-consumer
项目,服务消费者,会调用 lab-39-skywalking-dubbo-provider
项目提供的 User Service 服务。
创建 pom.xml
文件中,引入依赖。和「16.2.1 引入依赖」基本是一致的,胖友可以点击 pom.xml
文件查看。
在 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 入门》文章。
创建 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);
}
}
创建 ConsumerApplication 类,服务消费者的启动类。代码如下:
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}
}
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
使用 ProviderApplication 启动服务提供者,使用 ConsumerApplication 启动服务消费者。
① 首先,使用浏览器,访问 http://127.0.0.1:8079/user/get?id=1 地址,使用 Dubbo 调用 user-service-provider
服务。因为,我们要追踪下该链路。
② 然后,继续使用浏览器,打开 http://127.0.0.1:8080/ 地址,进入 SkyWalking UI 界面。如下图所示:
③ 之后,点击「拓扑图」菜单,进入查看拓扑图的界面,可以看到两个服务的小方块,以及对应的调用关系。如下图所示:
④ 再之后,点击「追踪」菜单,进入查看链路数据的界面。如下图所示:
示例代码对应仓库: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 项目即可。
修改 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
环境变量,可以实现自定义抽样收集数量。
通过 IDEA 的「Run/Debug Configurations」配置使用 SkyWalking Agent。如下图所示:
通过设置 SW_AGENT_SAMPLE
环境变量为 1,实现每 3 秒只收集一个链路数据,方便演示测试。
① 首先,使用浏览器,疯狂访问下 http://127.0.0.1:8079/demo/echo 地址,请求下 Spring Boot 应用提供的 API。
② 之后,在 SkyWalking UI 的查看链路追踪的界面,看到只有部分链路被收集。😈 这里暂时就不贴图了,嘿嘿~
有一点要注意,SkyWalking Agent 提供的插件,是基于我们使用的框架的方法,通过 AOP 的方式进行追踪,所以可能存在不兼容的情况,毕竟框架的代码在不断迭代,方法可能存在一定的变更。因此,一定要注意查看《SkyWalking —— Supported-list.md》文档。
当然,文档罗列的是 SkyWalking 开发团队已经测试过,经过确认支持的框架的版本。具体的,胖友最好动手测试下,自己再验证一波。如果碰到不支持的情况,可以查看对应框架的 SkyWalking 插件代码,比较容易就能定位到源码落。
嘻嘻,想要对 SkyWalking 做进一步深入的胖友,欢迎来看艿艿写的《SkyWalking 源码解析》。美滋滋~
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_42073629/article/details/106775584
内容来源于网络,如有侵权,请联系作者删除!