Skywalking 是一个优秀的国产开源APM组件,是一个对 Java 分布式应用程序集群的业务运行情况进行追踪、告警和分析的系统。2015年由个人吴晟开源 , 2017年加入Apache孵化器。
支持 SpringBoot、SpringCloud、dubbo 集成,代码无侵入,通信方式采用 GRPC,性能较好,实现方式是 Java 探针,支持告警,支持JVM监控,支持链路追踪,支持全局调用统计等等,功能较完善。
整体架构
- 上面部分(Agent):负责从应用中收集信息,发送给SkyWalking OAP服务器。
- 中间部分(SkyWalking OAP):负责接受Agent发送的Tracing数据信息,然后进行分析(Analysis Core),存储到外部服务器(Storage),最终提供查询功能。
- 右边部分(Storage):Tracing数据存储, 目前支持ES、MySQL、Sharding Sphere、TiDB、H2多种存储器,默认使用H2。
- 左边部分(SkyWalking UI):提供控制台,查询链路,数据展示等等。
SkyWalking支持三种探针:
- Agent:基于ByteBuddy字节码增强技术实现,通过jvm的agent参数加载,并在程序启动时拦截指定的方法来收集数
- SDK:程序中显式调用SkyWalking提供的SDK来收集数据,对应用有侵入。
- Service Mesh:通过Service mesh的网络代理来收集数据。
环境搭建
- skywalking agent和业务系统绑定在一起,负责收集各种监控数据。
- Skywalking oapservice是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中;接受skywalking webapp的前端请 求,从数据库查询数据,并返回数据给前端。Skywalking oapservice通常 以集群的形式存在,部署多个oap服务。
- skywalking webapp,前端界面,用于展示数据。
- 用于存储监控数据的数据库,比如mysql、elasticsearch等。
解压目录
搭建OAP服务
- 配置存储:apache-skywalking-apm-bin\config\application.yml
默认使用H2,如果使用H2不需要做任何操作。
使用Mysql
修改存储类型为Mysql
配置Mysql相关信息
在Mysql中建立swtest表,采用latin1字符编码,可以避免索引长度的问题,表的创建是自动的,然后需要在包中添加MySQL依赖;
在oap-libs目录下加入Mysql依赖
web-ui配置:apache-skywalking-apm-bin\webapp\webapp.yml
启动:apache-skywalking-apm-bin\bin
使用脚本startup.*,会同时启动oapService和webappService脚本。
启动成功会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui skywalking-oap-server服务启动后会暴露11800 和 12800 两个端口,分别为收集监控数据 的端口11800和接受前端请求的端口12800,修改端口可以修改config/applicaiton.yml
访问 http://127.0.0.1:18080/
表自动创建
SkyWalking使用
背景:通过SkyWalking做链路追踪并采集相关日志
用户调用 --> GateWay服务 --> User服务 --> Mysql
服务启JVM参数
// agent的jar地址
-javaagent:E:\java\skywalking\skywalking-agent\skywalking-agent.jar
// 接入的服务名称
-DSW_AGENT_NAME=text
// oap服务地址
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
服务:GateWay
@Slf4j
@RestController
@RequestMapping("/gateway")
public class GateWayController {
@Autowired
private UserClient userClient;
@GetMapping("/getUserIdByGateWay")
public String getUserIdByGateWay(@RequestParam String id){
log.info("调用GateWay服务-getUserIdByGateWay接口-参数id:{}", id);
return userClient.getUserId(id);
}
}
通过 fegin 调用 User服务
@FeignClient(
value = "user",
url = "127.0.0.1:8090"
)
public interface UserClient {
@GetMapping("/user/getUserId")
String getUserId(@RequestParam String id);
}
添加SkyWalking采集日志依赖
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>版本号</version>
</dependency>
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %highlight(%-5level) | %yellow(%thread) | %cyan(%logger{50}) | %highlight(%msg) %n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- skyWalking采集日志 -->
<appender name="skyWalking-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.TraceIdPatternLogbackLayout">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level logger_name:%logger{36} - [%tid] - message:%msg%n</pattern>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="skyWalking-log" />
</root>
</configuration>
启动并添加JVM参数
服务:User
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/getUserId")
public String getUserId(@RequestParam String id) {
log.info("调用User服务-getUserId接口-参数id:{}", id);
return JSONObject.toJSONString(userMapper.selectById(id));
}
}
通过mybaits-puls调用数据库
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
并且以同样的方式添加SkyWalking采集日志
启动并添加JVM参数
两个服务启动成功后,SkyWalking-ui会显示服务
服务调用
服务调用成功,然后查看SkyWalking-ui
扩展图能充分的体验到服务之间的调用关系。
链路图,可以看调用的接口,接口之间的一个链路,并且能看到接口是属于哪个服务
日志