目录
- 准备
- 调整配置
- 接入多个微服务
- 网关项目调整
- order-seata项目
- stock-seata项目
- 测试
- 接入网关微服务
- skywalking持续化到mysql
- 自定义链路跟踪
- pom .xml
- orderController
- OrderService
- OrderDao
- OrderTblMapper.xml
- 测试
- 性能剖析
- 日志
- tid打印
- pom.xml
- logback-spring.xml
- 日志收集
- 启动项目
随着业务规模的不断的增大, 系统的复杂度也越来越高, 我们的软件架构也进入到了分布式的阶段, 服务按照不同的维度进入到了分布式的阶段, 服务按照不同的维度进行拆分, 每一次的请求可能跨越多个微服务, 这样就导致我们每一次请求都有可能出现异常. 传统的日志监控方式无法满足调用链路追踪, 这就导致定位/诊断服务异常变得异常复杂.
准备
下载
webapp: Ul 前端(web 监控页面)的jar 包和配置文件;
oap-libs: 后台应用的 jar 包,以及它的依赖 jar 包,里边有一个 server-starter-.jar 就是启动程序;
config: 启动后台应用程序的配置文件,是使用的各种配置
。bin: 各种启动脚本,一般使用脚本 startup.来启动 web 页面 和对应的 后台应用
。oapService.“:默认使用的后台程序的启动脚本;(使用的是默认模式启动,还支持其他模式,各模式区别见 启动模式)。oapservicelnit.”:使用 init 模式启动;在此模式下,OAP服务器启动以执行初始化工作,然后退出oapServiceNolnit,:使用 no init模式启动;在此模式下,OAP服务器不进行初始化。
webappService.:Ul 前端的启动脚本:
。startup.:组合脚本,同时启动 oapService.:、webappService.* 脚本;
’agent:
。skywalking-agent.jar: 代理服务jar 包
config: 代理服务启动时使用的配置文件
。plugins:包含多个插件,代理服务启动时会加载改目录下的所有插件(实际是各种 jar 包),比-SiringCloud Gateway,则需要把对应的 jar 包拷贝到 plugins
调整配置
- 修改webapp.yml
启动成功后会启动两个服务,一个是skywalking-oap·server,一个是skywalking-web·ui: 8868skywalking-oap-sen2服务启动后会暴露11800 和 12800 两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/applicaiton.yml
接入多个微服务
输入localhost:8868,可以接入skywalking管理界面,
- 在这三个项目上改造
网关项目调整
- 改为order-seata项目的服务名
order-seata项目
下载客户端收集的jar
- 注意: 很多文章没有说明
idea启动调整
-javaagent:D:\system\apache-skywalking-java-agent-8.10.0\skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=OrderSeata -Dskywalking.collector.backend_service=127.0.0.1:11800
- Dskywalking.agent.service_name 服务名
- -Dskywalking.collector.backend_service 暴露的端口
- -javaagent:D:\system\apache-skywalking-java-agent-8.10.0\skywalking-agent/skywalking-agent.jar 是上面解压后的路径
stock-seata项目
idea启动调整
-javaagent:D:\system\apache-skywalking-java-agent-8.10.0\skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=StockSeata -Dskywalking.collector.backend_service=127.0.0.1:11800
测试
记得启动nacos、seata、sentinel服务端
访问项目http://127.0.0.1:8088/order-service/order/add
- 到这里说明,skywalking集成微服务算成功咯
接入网关微服务
- 在网关上新增配置
-javaagent:D:\system\apache-skywalking-java-agent-8.10.0\skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=api-service -Dskywalking.collector.backend_service=127.0.0.1:11800
先访问http://127.0.0.1:8088/order-service/order/add接口
- 就显示了一个api-service得服务,但是对应的请求日志没有显示, why? 什么情况
- api-service这个服务我都是刷新几次后,才显示,估计是有延迟。
找到下载解压后agent包
移动到如下目录下
再重新启动 我们在测试的三个项目
现在显示访问记录,gateway的一个小问题,需要这样特殊处理一下
skywalking持续化到mysql
默认使用h2存储,也就是所谓的存在内存中,服务重启后,记录就会丢失
修改成mysql
- 修改mysql的账号和密码,以及url地址
- 创建数据库,表会自动创建
D:\system\apache-skywalking-apm-9.0.0\apache-skywalking-apm-bin\bin
启动startup.bat,正常启动成功后,skywalking是有两个窗口的,但是这里启动后,会关闭skywalking-collector,说明这个服务报错咯
来到log日志查看原因
- 有没有看着很熟悉的感觉?
初步定位,感觉就是缺少mysql驱动导致的。
- 随机找一个幸运儿项目,找到mysql驱动
- 把对应的jar,放到该目录下面,重启bin
- 对应的数据库会自动创建很多的表
- 记得这三个项目也要重新启动,不然,不会加载到skywalking里面去
访问http://127.0.0.1:8088/order-service/order/add,出现请求路径。
这时,我们再重启一下服务,看看,数据是否存在,如果存在,则说明mysql持久化成功
自定义链路跟踪
- 在order-seata项目上,新增链路跟踪代码
pom .xml
<!--skywalking自定义链路跟踪-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>9.0.0</version>
</dependency>
- 注意跟下载的skywalking版本一直,我下载的是9.0.0版本的,所以,写这个版本,不然,会有一些奇奇怪怪的问题
orderController
/**
* 获取id获取数据
* @param id
* @return
*/
@RequestMapping("/get")
public OrderTbl get(Integer id){
return orderService.get(id);
}
OrderService
package com.lcs.springcloud.service;
import com.lcs.springcloud.dao.OrderDao;
import com.lcs.springcloud.entity.OrderTbl;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Autowired
OrderDao orderDao;
public void insert(OrderTbl orderTbl) {
orderDao.insert(orderTbl);
}
/**
* 获取id获取数据
* @param id
* @return
*/
@Trace
@Tags({
@Tag(key = "id", value = "arg[0]"),
@Tag(key = "order", value = "returnedObj")
})
public OrderTbl get(Integer id) {
return orderDao.get(id);
}
}
OrderDao
package com.lcs.springcloud.dao;
import com.lcs.springcloud.entity.OrderTbl;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderDao {
void insert(OrderTbl orderTbl);
/**
* 根据id获取数据
* @param id
* @return
*/
OrderTbl get(Integer id);
}
OrderTblMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lcs.springcloud.dao.OrderDao">
<!-- 主键自增长的插入 -->
<insert id="insert" parameterType="com.lcs.springcloud.entity.OrderTbl" useGeneratedKeys="true" keyProperty="id">
insert into order_tbl(product_id,total_amount,statu) values(
#{product_id},
#{total_amount},
#{statu}
);
</insert>
<select id="get" resultType="com.lcs.springcloud.entity.OrderTbl">
select * from order_tbl where id = #{id}
</select>
</mapper>
测试
访问http://127.0.0.1:8088/order-service/order/get?id=12
- id和order就是我们定义的名称,通过这里可以看到对应的传参以及返回值
性能剖析
controller的代码调整
/**
* 获取id获取数据
* @param id
* @return
*/
@RequestMapping("/get")
public OrderTbl get(Integer id) throws InterruptedException {
//延迟2秒
TimeUnit.SECONDS.sleep(2);
return orderService.get(id);
}
- 新增一个延迟2秒的代码,重新启动项目
- trace 是看界面
- profile 是分析
- 新建一个任务
- 奇葩问题,一直没有分析报告生成,搞不懂为什么
- 还没有删除的入口,服了
日志
tid打印
pom.xml
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>9.0.0</version>
</dependency>
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志输出格式 -->
<property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] %green(%-5level) [%thread] %yellow([%tid]) %cyan(%logger{50}) : %msg%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 默认日志打印的格式 -->
<!--<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>-->
<!-- 配置了skywalking的traceId的日志打印的格式 -->
<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 name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="STDOUT"/>
</appender>
<root level="info">
<appender-ref ref="ASYNC_STDOUT"/>
</root>
</configuration>
- 配置logback并在日志中打印traceId,在日志输出格式中添加%tid即可
启动项目
日志收集
最后配置日志收集,需要在logback的配置文件中再添加一个appender
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<neverBlock>true</neverBlock>
<appender-ref ref="STDOUT"/>
</appender>
<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="grpc-log" />
<appender-ref ref="ASYNC"/>
</root>
</configuration>
启动项目
-javaagent:D:\system\apache-skywalking-java-agent-9.0.0\skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=OrderSeata -Dskywalking.collector.backend_service=127.0.0.1:11800
- idea中配置
- 记得调整上面的时间,不然有时候不显示数据,这设计有点坑
项目代码