【SkyWalking】分布式环境下的链路追踪技术

SkyWalking链路追踪技术


文章目录


一. 认识SkyWalking

SkyWalking解决了什么问题?-----》微服务架构中,各个服务之间调用关系错综复杂,所以需要一个能捋清复杂情况下调用关系的解决方案,这就是SkyWalking,目前最强大的链路追踪技术;

要使用SkyWalking,需要给我们的项目中绑定一个agent探针,绑定后,SkyWalking就会将你项目整体的监控数据反馈给SkyWalking oapservice,SkyWalking oapservice就是SkyWalking的服务端,oapservice会将这些监控数据做处理,然后存储到数据库中:SkyWalking支持的数据库有很多种:ES,Mysql等等很多都支持;然后SkyWalking 提供了一个前端的可视化ui界面,我们程序员可以通过这个ui界面方便的查看到我们项目整体的数据,因为这个前端界面会向oapservice发送请求查询数据;

二、下载SkyWalking

1.下载SkyWalking

下载网址:http://skywalking.apache.org/downloads/
点击Distribution选择要下载的版本----》我们可以看到skywalking它每一个版本都提供了两份:
其中v8.5.0 for ElasticSearch 6 是针对于es6的,也就是说它的oapservice收集到数据后并处理后,会将其存储到es6中;
另一个版本是针对于其他数据库进行存储,比如H2,Mysql,ES7等等(我也不知道为什么要把ES6,ES7分成两部分?)
在这里插入图片描述

2. 启动方式

下载好后,解压,然后打开bin文件夹,然后双击startup.bat命令就可以启动skywalking;
双击startup.bat—》它会帮我们同时启动oapservice.bat与webappService.bat;
假如你是用的liunx系统,那么你需要点击startup.sh进行启动,window系统下用startup.bat;
在这里插入图片描述
在这里插入图片描述

3. 目录文件解释

1.webapp文件夹

这个文件夹中放的是:skywalking的ui前端界面的jar包跟yaml配置文件;
如果你要修改它的前端ui界面的配置,就要在这个文件夹下的webapp.yaml中进行修改;
通过都是需要修改的,因为这个ui前端界面的默认端口号是8080,基本不会用这个端口,容易重复且易被攻击
在这里插入图片描述
在这里插入图片描述
这是前端界面配置文件打开后的样子;
在这里插入图片描述

2.config文件夹

这个文件夹中放的就是常用的配置文件
在这里插入图片描述
这里面最重要的文件就是这个application.yml
在这里插入图片描述

2.1 application.yml文件详解
2.1.1 监控数据存储方式修改

打开这个文件,里面有个
storage:
selector: ${SW_STORAGE: h2}
这个表示oapservice读取到的监控数据的存储方式,可以看到它默认的存储方式就是采用的h2数据库,这是一种基于内存的数据库,我们不用它,因为它基于内存,只要一重启skywalking,这些监控数据就会消失;
注意:skywalking最优的监控数据存储方式是es,但是很多人可能不懂es,也可以用mysql替代;
在这里插入图片描述

3. agent文件夹

这个文件夹里有个最重要的东西:skywalking-agent.jar,这个jar包到时候需要跟我们的微服务进行绑定,绑定后oapservice才能从我们的微服务中获取监控数据;
在这里插入图片描述

3. bin文件夹

这个文件夹里放的都是一些启动脚本;

5. oap-libs

这个文件夹下放的是:oapservice服务器所用的jar包

三、启动skywalking

1.启动成功界面

双击startup.bat命令后,出现下面这个界面就表示skywalking启动成功;
在这里插入图片描述

2.oapservice的日志文件

oapservice已经自己集成好了日志功能,它在使用过程中就会输出日志;
日志记录会被输出到logs文件夹中下的两个.log文件中,一个是记录的前端ui界面的日志,一个是记录后端oapservice的日志;
在这里插入图片描述在这里插入图片描述

3. oapservice的端口

oapservice自动暴露了两个端口,11800端口和12800端口;
11800端口是oapservice用来收集微服务监控数据的端口,
12800是oapservice用来接收前端ui界面请求的端口;

我们也可以通过config文件夹下的application.yaml来修改这些端口号;

注意:在我们自己的微服务中,要将oapservice的端口号告诉给我们的微服务,否则我们自己的微服务是不知道oapservice的端口的,就没有传递监控数据给oapservice了

4. 打开前端ui界面

你在webapp文件夹下的webapp.yml中将前端ui界面的端口号配置好后,你可以直接在你的浏览器中使用 localhost:你配置好的端口号,来访问前端ui界面;
这就是打开后的样子;

5. 将skywalking与我们自己的微服务绑定

通过上面的操作:修改前端ui界面端口号,双击startup.bat,我们已经成功的启动好了前端ui界面,也成功了启动好了oapservice服务了;
现在还差的是:将我们自己的微服务与skywalking进行绑定,以便skywalking能从我们的微服务获取监控数据;

5.1 在windows环境下绑定skywalking

这种方式是在idea中配置,首先找到Edit Configuration,点击打开;在这里插入图片描述
我们选择gateway这个服务,(这里只是以gateway服务作为一个例子用来讲解)
然后找到VM options,在里面按照图片中的格式进行配置;
注意点1:这里是通过jvm的参数来进行的配置,可以达到对代码无侵入的效果;
注意点2:下面截图中VM options中是写了注释的,这是为了我们学习时方便理解,你真正要去配的时候,不能往里面加注释,因为VM options中是识别不了的,会报错;

配置好后–》再点击ok完成配置
在这里插入图片描述

5.2.1 查看结果

我们进入到前端ui界面,点击右上角的刷新(我们可以点击左边的"自动",当"自动"变成蓝色后,前端ui界面就会按照你指定的频率每隔几秒刷新一次界面);
但是我们刷新后,只是在上面看到一个api-service,这是我们在gateway服务的VM options中给gateway服务取的名字,我们只看到了这个名字,刷新后下面的界面也看不到任何东西;
然后我们点击上方的拓扑图,
在这里插入图片描述
拓扑图里面也只是有一个服务名称,但是没有任何数据,这是为什么呢?
在这里插入图片描述

5.2.2 skywalking与gateway之间存在的问题

这里一定要注意:skywalking在默认情况下是不会显示gateway的,就算你把gateway服务跟skywalking的skywalking-agent.jar进行了绑定,在skywalking前端界面中也是不会显示gateway的任何信息的;

解决办法:
第一步:打开skywalking安装目录下的agent文件夹在这里插入图片描述
第二步:再打开plugins文件夹,这个文件夹中是skywalking集成的所有插件,在这里面可以找到很多jar包,包括mysql,rocketmq等等很多,但你就是找不到gateway的jar包,所以才导致出现上面的问题;
所以你只需要将gateway的jar包放入plugins文件夹里面就可以了
在这里插入图片描述
第三步:gateway的jar包到哪里去拿呢?
其实skywalking已经帮我们准备好了gateway的jar包,在我们下载skywalking的安装包时,gateway的jar包已经包含在里面了;
我们找到optional-plugins文件夹,这个文件的意思是:可选的插件;
在这里插入图片描述
点开文件夹后,会看到里面就有gateway的jar包,有两个,我们可以选择2.1.x那个,这个更新一点;

然后将它复制一份,复制到plugins文件夹中,然后重启skywalking服务;这样就可以了;
在这里插入图片描述

5.2.3 再次查看结果
1. 全局响应时间与全局心跳时间

重启后,我们再次打开skywalking的前端ui界面,就能在下面的页面中看到两个板块;
左边的折线图表示:全局的响应时间
右边的图表示:全局的心跳时间
在这里插入图片描述
我们还可以点击界面下方的时间,选择最近多少分钟进行查看;在这里插入图片描述

2. 服务,端点,实例

然后我们还可以看到下图圈起来的部分:
最左边的Services Load 表示当前服务的硬件性能,比如cpu等等;
Slow-Services表示慢加载;
Un-Health Services表示不健康的服务;
Slow Endpoints表示慢端点,就是慢接口的意思,就是说你当前服务有哪些接口比较慢;

然后还有个部分叫"当前实例",如果你当前这个服务是做了集群的,那么你点击当前实例是可以看到好几个实例的,下图只显示了一个,因为我们作为案例的这个gateway服务没有做集群;

在这里插入图片描述

3. 拓扑图

然后我们再点击拓扑图,就会显示成这个样子;
意思就是:User用户发送请求到了api-service,也就是gateway,然后gateway又调用一台192.168.65.106:8020的机器(这台机器实际上是订单服务),为什么订单服务在拓扑图中没有显示服务名称而是显示ip地址跟端口呢?这是因为我们现在只是将gateway服务与skywalking-agent.jar绑定了,订单服务没有跟它绑定,所以只是显示ip与端口;
在这里插入图片描述

4. 追踪

我们可以点到追踪界面,追踪界面有三种查看形式,列表,树结构,表格;
图中展示的是表格的显示形式:
图中红色圈起来这里有个"/order/get",意思就是你这次发起的请求是"/order/get",
然后发起这次请求,从上往下看,你首先经过了gateway的RoutingFilter接口,也就是经过了路由过滤器,
然后再经过了gateway的sendRequest接口,将请求发送了出去;
那既然是发送请求给订单服务的"/order/get"接口,那为什么sendRequest接口下面就没有显示了呢?
这是因为我们还没有把订单服务跟skywalking-agent.jar进行绑定,skywalking就不会显示在订单服务中的调用链路,所以这里调用链路只显示到了gateway;
在这里插入图片描述

5. 性能剖析,日志,告警

这三个部分如果我们要看的话,需要做单独的处理,这里还没处理所以看不到,后面再讲;
在这里插入图片描述

5.2 在linux环境下绑定skywalking

5.3 将多个服务与skywalking进行绑定

以上案例只将gateway一个服务与skywalking进行了绑定,实际开发过程中,我们会将很多服务都跟skywalking进行绑定,也很简单,还是只需要在每个服务的VM options中配置就行了;

6. skywalking中持久化数据到数据库

6.1 h2数据库:skywalking的默认存储方式

skywalking默认是将数据存储到h2数据库中的,这是一个内存数据库;
如果将这些监控数据存储到内存中,有两个弊端:
1.一旦你的skywalking重启,内存中的这些监控数据必然会丢失,但其实影响也不是很大,因为监控数据基本都是实时的,没有必要保存下来,更没有必要查看一个月以前的监控数据;就这个方面来说,h2数据库也不是不可以;
2.但是当我们skywalking长期启动,会有越来越多的监控数据被存入内存中,最终就会导致内存爆满,到时候我们依然要重启skywalking,所以从这个方面来说,h2数据库并不合适,所以可以采用mysql,存储到mysql后,我们定时去清空就好了;
在这里插入图片描述

6.2 skywalking的持久化方式

1. 修改配置文件

我们如何修改skywalking的存储数据库?—》找到config文件夹------》找到application.yml,找到110行,将h2改成mysql,----》最后找到172行,配置mysql的ip地址,端口号,数据库名称,账户密码等信息;

在这里插入图片描述
在这里插入图片描述

2. mysql中建数据库

然后在mysql中建好配置文件中的数据库,这个库名要跟我们配置文件中配置的名称swtest一致,建好库之后我们就不用管了,因为skywalking在被启动时,自动在我们建好的这个库中创建它需要的表;
在这里插入图片描述

3.skywalking启动时的bug

在我们修改好配置文件,将h2改成mysql后,再启动skywalking就会出现bug:双击startup.bat时出现闪退,无法启动成功,此时我们找到logs文件夹下的skywalking-oap-server.log这个日志文件,我们点进去拉到下面,就能看到如下报错提示:获取不到驱动实例;

造成这个bug的原因是什么呢?是因为skywalking的plugins文件夹下没有mysql的驱动jar包,我们可以到自己的maven仓库中找到mysql驱动包,复制到plugins文件夹下即可
在这里插入图片描述
maven仓库中mysql驱动包长这个样子
在这里插入图片描述

4. 再次启动skywalking

等我们处理好上面的bug后,我们再次启动skywalking,它就会自动在我们指定好的mysql数据库中建表;
下图是建好后的样子,可以看到skywalking建了非常多的表;
在这里插入图片描述
使用mysql作为skywalking存储数据的好处是什么呢? 当你重启skywalking后,之前的监控数据依然还在,也就是你打开前端ui界面,还能看到之前的数据;

7. 自定义skywalking的链路追踪

7.1 为什么需要自定义链路追踪?

什么意思呢?为什么要自定义skywalking的链路追踪呢?

在skywalking,只要你的服务跟skywalking进行了绑定,当你访问这些绑定后的服务时,我们就能在skywalking前端ui界面中的链路追踪板块中,看到本次请求完整的调用链路;就像下图所示,就是skywalking默认的调用链路;

但是:上面展示的调用链路中,skywalking只是展示了接口的url,比如关于/order/add这个请求,它就只是展示了/order跟/add,如果有一天,我还想它展示的更清楚,比如/add这个接口中,它最终调用了一个create方法,我还想skywalking把create方法也在调用链路中展示出来,并且还要将create方法的入参,返回值这些都记录展示出来,这就方便我们以后对问题做排查;
这时候就需要我们自定义调用链路了;
在这里插入图片描述

7.2 如何自定义链路追踪?

1. 第一步:引入依赖

我们需要在项目中引入依赖,你哪个服务需要跟skywalking绑定,你就在这个服务的pom文件中加入这个依赖;
或者你直接把这个依赖加到总pom文件中;

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

这里需要注意一下这个工具的版本是8.5.0,这个工具的版本要跟你下载的skywalking版本保持一致,你skywalking下载的是8.5.0,那么你这个工具也要用8.5.0;

2. 在对应的业务方法上添加注解@Trace,@Tag,@Tags

现在你有一个订单服务,你已经将订单服务与skywalking绑定了,
并且你的Controller方法如下:

@RestController
@RequestMapping("/order")
public class orderContorller{

	@RequestMapping("/get/{id}")
	public order get(@PathVariable Integer id){
		return orderService.get(id);
	}

	@RequestMapping("/all")
	public List<Order> getAll() throws InterruptedException{
		return orderService.all();
	}
}

你的service层的方法如下:

@Override
public List<Order> all() throws InterruptedException{
	TimeUnit.SECONDS.sleep(2);
	return orderMapper.selectAll();
}

@Override
public Order get(Integer id){
	return orderMapper.selectByPrimaryKey(id);
}

由于你已经将订单服务与skywalking进行了绑定,那么当你在调用订单服务的all接口时,你是可以在skywalking中看到"/order/all"的完整调用链路的;同理get请求也是一样;
但是controller中,你的all接口还调用了service层的all()方法,你此时在"/order/all"的调用链路中是看不到service层的all()方法的;

而skywalking已经帮我们提供好了解决方案,我们的目的是想在调用链路中也看到service层的all()方法与get()方法,
我们可以在service层的all()方法与get()方法上加上@Trace注解;

2.1 @Trace

@Trace的作用:被@Trace修饰的方法,只要这个方法在某个请求中被调用到了,那么这个方法也会被展示到skywalking的调用链路中,本身它是不展示的,因为skywalking的调用链路中本身只展示接口,你service层的方法又不是接口;
用法:直接写在你想要加入调用链路展示的方法上即可

2.2 @Tag,@Tags

@Tag的作用:上面的@Trace只是将方法加入到了调用链路中,但是我们还想要在调用链路中看到这个方法的入参,返回值,就需要用到@Tag;
这里要分两种情况:
第一种情况,你这个方法没有入参,只有返回值,我想在调用链路中展示这个方法的返回值,就要给@Tag指定一个key,一个value;key可以随便指定,如果你这个@Tag是要用来展示返回值的,你可以直接把key设置为"返回值";
这个key其实就是用来控制在skywalking中显示的东西的,就像下图这样:getAll这里就会变成"返回值",那么图中为什么会显示成getAll呢,这是因为我学习的教程的作者把这个key设置成了“getAll”,但实际上用getAll并不好区分,一眼看到它并不知道是什么意思,所以我给它换成了"返回值";
在这里插入图片描述
指定value时呢,就是固定的写法了,必须写成value = “returnObj” ,skywalking底层已经帮我们做好了,因为每个方法的返回值类型不一样,所以skywalking就干脆用returnObj来代替这个返回值,只要你写value = "returnObj"就代表你要在展示这个方法返回值的意思; 上图中被蓝色框起来这部分,实际上就是returnObj的值;

@Override
@Trace
@Tag(key = "返回值", value = "returnObj")
public List<Order> all() throws InterruptedException{
	TimeUnit.SECONDS.sleep(2);
	return orderMapper.selectAll();
}

第二种情况:你这个方法有入参,也有返回值,此时就必须用到@Tags,@Tag不够用;
@Tags中要用大括号包起来,里面要有两个@Tag,一个@Tag用来表示返回值,一个@Tag用来表示入参,表示入参时,value要用arg[0]来表示,为什么呢?因为get方法只有一个入参 Integer id,skywalking把入参封装成了一个数组,现在只有一个入参,所以下标0就表示Integer id这个参数,所以用arg[0]来表示;
注意:如果这个get方法有两个入参,那么在@Tags的大括号就要有三个@Tag才可以了,另一个入参就要用arg[1]来表示了;
注意:@Tags中的所有@Tag都是它的一个属性,在注解中,不同的属性之间,如果其中一个属性中有多个元素,就要用大括号将其装起来;

@Override
@Trace
@Tags({@Tag(key = "返回值", value = "returnObj"),@Tag(key = "参数1", value = "arg[0]")})
public Order get(Integer id){
	return orderMapper.selectByPrimaryKey(id);
}
2.3 注意事项
  1. @Trace,@Tag,@Tags一定要写在业务方法上,写在controller的接口上是没有用的,因为skywalking默认展示的调用链路中本来就是展示的接口;
  2. 当我们在用@Trace,@Tag,@Tags自定义调用链路时,一定必须给业务方法先加上@Trace,再考虑加上@Tag,@Tags,如果没有先加上@Trace,那么@Tag,@Tags是不会起作用的,按照正常逻辑也能想通,你这个方法都没有添加进调用链路中,你怎么可能展示它的返回值与入参;
3. 检验结果
3.1 发起请求

我们先调用一次all接口,为什么要先调用一次?因为只有被调用了的接口才会有调用链路,你这个请求都没有发送,skywalking怎么展示这个请求的调用链路呢?
在这里插入图片描述

3.2 查看调用链路,点击清空,“持续时间”,“开始时间”

上面我们发起请求后,我们再打开ui前端界面的链路追踪界面;
这里要注意:此时可能看不到我们刚才发送的/order/all请求,因为可能有延迟;我们点击右上角的"清空"按钮;
然后再点击左边的"持续时间",将其换成"开始时间",“持续时间"的意思就是:将你所有的请求按照调用时间的长短进行排序,排在上面的请求,说明它消耗的时间越长,可以方便我们排查;
“开始时间"的意思是:按照这些请求的发生时间排序,排在上面的是最近一次发起的请求;所以这里为了我们学习的方便,我们将其换成"开始时间”,找到我们刚才发起的”/order/all"请求
在这里插入图片描述

3.3 查看调用链路中是否有显示业务方法

根据上面的操作后,我们在左边成功的看到了刚才发起的"/order/all"请求,点击它,然后看到右边它的调用链路;
首先第一行是一个"/order/all",这个可以不用管它,它只是skywalking为了方便我们区分每一个不同的请求,给这个调用链路取的一个标题;
第二行:就是可以看到,请求进来后,首先经过了gateway的RoutingFilter路由过滤器;RoutingFilter其实就是gateway中的一个接口,因为skywalking的调用链路中,如果没有经过@trace,@Tag,@Tags等自定义调用链路,它是只展示接口的;
第三行:然后经过了gateway的sendRequest接口;
第四行:再经过了oder服务的/order/all接口,也就是说这个请求被gateway分配到了订单服务的/order/all接口;
第五行:再经过了com.tulingxueyuan.order.service.impl.OrderServiceImpl.all()方法,这里就是显示的我们service层中的all方法了;
注意1:它这里显示的是这个业务方法的完全路径,com.tulingxueyuan包下的order模块下的service包下的impl包下的OrderServiceImpl类下的all()方法,它是这样显示的;
注意2:图中业务方法是没有显示完整的,我们左键点击它,就能够看到这个all方法的完整信息
在这里插入图片描述
这个就是点开all()方法后展示的样子,能看到服务名称,服务实例,端点,以及返回值;
服务名称与服务实例就不说了,
端点:其实就是指的接口,但是由于你这个all()方法是service层中的,接口是指controller里面的,所以all()并不能完全称为端点,但是不管service层的方法,还是controller层的方法都是属于方法,本质上没有区别,所以你service层中all()方法显示在端点这一栏也没有问题;
返回值:最后一项getAll那一栏就是表示all()方法的返回值;为什么这里显示的是getAll呢,这是因为我看的教程,作者它在给all()设置@Tag时,key使用的是"getAll" ,所以这里我们点开all()方法的最后一栏显示是getAll,而不是我们自己设置的"返回值";
在这里插入图片描述
在这里插入图片描述

最后还需要注意的是:这里最后一栏能显示为【Order{id=1,productId=1,totalAmount=90,status=1}】,这是因为你这个业务方法中的Order类是重写了toString方法的,如果没有重写,那么最后一栏这里显示的就是地址值;
在这里插入图片描述

最后我们再发送一个/order/get/1请求,那么我们点开它就是这个样子
在这里插入图片描述

8. 性能剖析

性能剖析就是图中的这个板块:
我们可以看到,在我们做完上面所有操作后,性能剖析这个界面依然是没有数据的,显示No Data;
在这里插入图片描述

1. 性能剖析的作用

当我们发送了一个skywalking管理返回内的请求,如果这个请求执行时间特别长,我们需要分析这里面到底是哪一句代码导致了它耗时特别长,这个时候就需要用到性能剖析了,这也是性能剖析的主要功能;

2. 新建监控任务,对接口进行监控

以/order/all这个接口为例子,我们发起了一个/order/all的请求,但是发现它特别慢;
在这里插入图片描述

这个时候,我们需要点击到性能剖析界面----》再点击右上角新建任务,就会弹出新建任务界面,需要我们设置参数;
首先:
服务:这一栏你要根据你要监控的那个接口所在的服务来指定,比如我现在要监控/order/all这个接口,它属于order-service这个服务,所以服务这一栏要选order-service
端点名称:你要监控/order/all这个接口,那么你这里就要填/order/all,注意前面是有斜杠的,不能少写一个/,写成 order/all;
监控时间:就选此刻,表示从现在开始监控;还可以设置时间,表示从什么时间才开始监控;
监控持续时间:我学习的教程里是选的默认的5min,不知道选其他的是否更合适;
起始监控时间:我学习的教程里就是用的默认值0,说实话,我也不知道这一项的意思;
监控间隔:我学习的教程里是用的默认的10ms,也就是每隔10ms监控一次;
最大采样数:这里设置的是5,也就是说你访问/order/all接口的请求数量必须达到5次,skywalking才会对其进行采样;
这些设置完后,我们再点击新建任务;
在这里插入图片描述

3. 测试

3.1 发送请求

上面设置的最大采样数是5,我们测试时该怎么操作呢?
我们在浏览器上发起请求,然后多点击几次刷新,只要发送请求数量超过5次就行;
在这里插入图片描述

3.2 查看是调用链路中是哪个接口执行慢

请求次数发送够后,我们再打开性能剖析界面刷新一下,就能看到性能剖析界面有数据了:
Task List:表示你现在有哪些任务;
Sampled Traces:表示采样样本,就是说在/order/all这个任务中,被skywalking捕捉到的关于/order/all的请求列表,我们可以看到左边被捕捉到了两次请求,一次消耗了2014ms,一次消耗了2016ms;
我们再点击第一个消耗了2014ms的/order/all,就可以看到右边的界面:start time表示本次调用的开始时间,第一行/order/all的Exc(ms)表示本次总的请求消耗了2014ms;
第二行all()方法中的Exc(ms)表示执行all()方法消耗了2012ms,Exc(%)表示执行时间的占比;
有了这个我们就能看到整个调用链路中,各个部分所消耗的执行时间了;
在这里插入图片描述

3.3 查看接口中是哪句代码执行慢

我们再点击分析:就能查看到底是哪句代码执行慢了;
点击分析后,下面就会显示出下面框起来这个界面
在这里插入图片描述
我们一直拉到最下面,就能看到被标绿的一行,这就是整个调用链路中,耗时最久的那句代码,它总共消耗了1986ms,下图这一行代码有两个1968,第一个1968是每一行都有的,后面第二个1968才表示当前这句代码消耗的时间;
第一个1968,是duration这一栏的,表示总持续时间;
第二个1968,是self duration这一栏的,表示自持续时间,也就是每一行的执行时间;
而我们再查看我们的代码,all方法里面确实有一行线程睡眠2秒的代码;
在这里插入图片描述
在这里插入图片描述

9. 日志

当我们发起一个请求后,我希望我的微服务的日志能针对本次请求,记录下来本次追踪链路的id,记录下来后,我们就可以在skywalking中根据链路的id将对应的调用链路记录给搜索出来,然后查看分析; 如果没有这个功能,我们在实际开发中发起一次请求后,没有链路追踪的id,很难找到对应的调用链路;
所以我们需要对我们项目的日志系统进行修改;

1. 三种日志框架

springboot默认的日志框架是logback,当然还有其他日志框架,比如log4j和log4j2
这里以logback作为案例来解释,下面是logback在我们项目中集成的案例,如果你们项目中是使用log4j或者log4j2作为日志框架,你们可以自己到网上搜索它们的配置方式;

1. 引入logback依赖
<!-- apm-toolkit-logback-1.x -->
<dependency>
	<groupId>org.apache.skywalking</groupId>
	<artifactId>apm-toolkit-logback-1.x</artifactId>
	<version>8.5.0</version>
</dependency>
2. 添加logback-spring.xml文件

首先,你需要先在对应服务的resource目录下添加logback-spring.xml文件,也就是说你想在哪个服务中加你就加;
logback-spring.xml格式如下: 注意:这个文件的名称一定要叫logback-spring.xml,这是springboot约定大于配置约定好的;

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<!-- 引入springboot默认的logback XMl配置文件 -->
	<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<!-- 日志的格式化,这里{magenta}后面加了一个[%tid],这个tid就是追踪链路的id,加了之后请求进来后,logback才能打印出这个追踪链路的id -->
		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
			<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
				<Pattern>CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
			</layout >
		</encoder>
	</appender>
	
	<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
			<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdMDCPatternLogbackLayout">
				<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid} [%thread] %-5level %logger{36} -%msg%n]</Pattern>
			</layout>
		</encoder>
	</appender>
	
	<!-- 设置Appender -->
	<root level="INFO">
		<appender-ref ref="console"/>
		<appender-ref ref="grpc-log"/>
	</root>
<configuration>	

在这里插入图片描述

3. 发送请求测试一下看日志是否有输出tid

我们前端发送一次请求,到后台查看,确实能看到一个TID,其中红色框圈起来的,就是tid,我们复制这个tid,然后拿到skywalking前端ui界面的追踪页面,用这个id查询到本次请求的调用链路;
在这里插入图片描述
在这里插入图片描述

4. 将输出到控制台的日志同步到skywalking的日志模块中

每次我们都到后台服务器的控制台查看日志非常不方便,我们可以将控制台输出的日志同步到skywalking的日志模块中,只需要在logback-spring.xml中加入下图红色圈起来这部分配置就行了,上面的logback-spring.xml文件中,我已经将这部分代码写进去了,直接粘贴即可;
在这里插入图片描述
有了这个功能后,我们以后就只需要在skywalking的日志模块统一的看日志就可以了,就不需要每次都切换到后台控制台查看;

5. 测试

上面的配置文件操作完后,我们再重启服务,再发送一下请求进行测试;

请求发送后,我们进入日志界面,如果没有看到东西,就可以点击右上角的搜索,这个搜索有一个刷新的功能;点击后就能看到下图这样的界面;
我们还可以点击右边的追踪ID,直接进入本次请求的调用链路中,比我们之前复制追踪id然后搜索来的更方便;
在这里插入图片描述

6. 注意事项:

如果你的skyalking服务器不是安装在本地的,那么你的项目是无法直接把日志信息传递到skywalking的日志模块的,需要你进行单独的配置;

首先打开你skywalking安装包下的agent文件夹

然后打开config文件夹
在这里插入图片描述
打开agent.config文件
在这里插入图片描述
然后将下图中红色框圈起来的部分,添加到配置文件中;
注意第一行的SERVER_HOST的ip地址这一栏,如果你的skywalking是在其他机器上,这个里就要填那台机器的ip地址;这一栏默认的地址是127.0.0.1,也就是它默认就是连的本机;
第二行的SEVER_POST这一栏就要填skywalking暴露出来对接agent的端口11800;这里默认就是11800
在这里插入图片描述
这样操作后,就完成了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值