Spring cloud alibaba--SkyWalking链路追踪

目录

1.什么是SkyWalking

2.SkyWalking环境搭建部署

2.1下载skywalking

 2.2启动服务

 2.3访问前端ui页面

 3.Skywalking接入微服务

3.1linux环境--通过jar包方式接入

3.2windos环境--在IDEA中配置SkyWalking

3.3wkywalking监控界面

3.4接入多个微服务

 4.Skywalking持久化跟踪数据

 4.1基于mysql的数据持久化

 5.自定义skywalking链路追踪

 6.性能剖析

 7.Skywalking集成日志框架

8.skywalking告警

8.1告警规则

 8.2webhook(网络钩子)


1.什么是SkyWalking

wkywalking是一个国产开源框架,由吴晟开源,2017年加入Apache孵化器。skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)框架而设计。它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

官网:Apache SkyWalking

下载:Downloads | Apache SkyWalking

文档:https://skywalking.apache.org/docs/main/v8.7.0/readme/

中文文档:SkyWalking 文档中文版(社区提供)

wkywaling主要功能特性:

(1)多种监控手段,可以通过语言探针和service mesh获得监控的数据

(2)支持多种语言自动探针,包括Java,.net Core 和Node.js

(3)轻量高效,无需大数据平台和大量的服务器资源

(4)模块化、UI、存储、集群管理都有多种机制可选

(5)支持告警

(6)优秀的可视化解决方案

2.SkyWalking环境搭建部署

.skywalking agent和业务系统绑定在一起,负责收集各种监控数据

.sykwalking oapservice是负责处理监控数据的,比如接收skywalking agent的监控数据,并存储在数据库中;接收skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。skywalking oapservice通常以集群的形式存在。

.skywalking webapp,前端界面,用于展示数据。

.数据库用于存储监控数据,比如mysql、elasticsearch等。

2.1下载skywalking

地址:Downloads | Apache SkyWalking

 下载的版本提供elasticSearch和mysql等的版本,我们使用mysql版本的。下载tar压缩包,解压后目录:

目录结构:

①webapp:UI前端(web监控页面)的jar包和配置文件;

ui页面的启动端口,可以修改webapp.yml,默认是8080

②oap-libs:后台应用的jar包,以及它依赖的jar包,里边有一个server-starter-*.jar就是启动程序;

③config:启动后台应用程序的配置文件,是使用的各种配置

在application.yml中可以配置使用的存储方式等信息,默认使用h2内存方式

④bin:各种启动脚本,一般使用脚本startup.*来启动web页面和对应的后台应用;

       oapService.*:默认使用的后台程序的启动脚本(使用的是默认启动模式);

       oapServiceInit.*:使用init模式启动;在此模式下,OAP服务器启动以执行初始化工作,然后退出

      oapServiceNoInit:使用no init模式启动;在此模式下,OAP服务器不进行初始化

      webappService.*:UI前端的启动脚本;

      startup.*:组合脚本,同时启动oapService.*,webappService.*脚本

⑤agent:

      skywalking-agent.jar:代理服务jar包

      config:代理服务启动时使用的配置文件

     plugins:包含多个插件,代理服务启动时会加载该目录下的所有插件(实际是各种jar包)

     optional-plugins:可选插件,当需要支持某种功能时,比如SpringCloud Gateway,则需要把对应的jar包拷贝到plugins目录下

 2.2启动服务

双击bin/startup.bat启动服务,同时会启动oapservice和webapp两个服务

 控制台没有答应启动是否成功以及端口等信息,当启动时会创建logs文件夹,分别生成skywalking-oap-server.log、webapp.log

 skywalking-oap-server会暴露11800和12800两个端口,分别为收集监控数据的端口11800和接受前端ui请求的端口12800,修改端口可以修改config/application.yml

 2.3访问前端ui页面

 根据webapp/webapp.yml中配置的ui的启动端口,访问ui页面

 3.Skywalking接入微服务

3.1linux环境--通过jar包方式接入

准备一个springboot程序,打成可执行jar包,写一个shell脚本,在启动项目的Shell脚本上,通过-javaagent参数进行配置SkyWalking Agent来跟踪微服务;startup.sh脚本:

#SkyWalking Agent配置
export SW_AGENT_NAME=springboot-skywalking-demo #Agent名字,一般使用‘spring.application.name’
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置Collector地址
export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认是300
export JAVA_AGENT=-javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
java $JAVA_AGENT -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar #jar启动

3.2windos环境--在IDEA中配置SkyWalking

在运行的程序配置jvm参数,如下图所示:

-javaagent:D:\software\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-DSW_AGENT_NAME=api-service
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800

3.3wkywalking监控界面

启动系统,访问接口,此时查看skywalking监控页面,没有任何数据,当前服务下拉有配置的api-service服务。

没有显示任何链路追踪信息的原因:agent/plugins目录中缺少gateway的jar包。

从agent/optional-plugins(扩展插件)中复制 gateway的jar包到agent/plugins目录中。

重新启动skywalking服务,以及springboot项目服务,在访问接口服务,skywalking控制台有检测数据。

仪表盘:显示服务、端点、慢服务等

 拓扑图(调用关系),user访问api-service,api-service调用的ip和端口,由于8084的服务还没有加入skywalking,所以此处只显示ip和端口

 追踪:调用服务的链路追踪,以及消耗的时间长短

3.4接入多个微服务

为了访问数据库,order的服务我们访问seate的项目,在OrderSeataApplication启动类的VM options中添加wkywalking的配置:

在StockSeateApplication启动类的VM options中添加:

 先启动seate、nacos服务,再启动这三个项目

此时nacos中是可以看到这几个服务的

访问接口服务,此时wkywalking控制台可以看到多个服务,多个调用的端点 

拓扑图显示了从user开始调用api-service网关服务,网关服务调用order-seata,order-seate调用数据库以及调用stock-seata;stock-seata调用数据库

 追踪:显示了服务调用的完整过程,以及花费的时间

 4.Skywalking持久化跟踪数据

默认使用H2(内存)数据库存储,在config/application.yml中配置,重启服务后数据会丢失。

 4.1基于mysql的数据持久化

(1)修改config/application.yml中的数据源为mysql

 (2)修改config/application.yml中的mysql连接配置

 (3)mysql中创建数据库,名字为(2)中配置的数据库名

 (4)重新启动startup.bat,发现oap-service服务启动不成功,查看skywalking-oap-server.log日志,显示获取不到数据库驱动。

 (5)从我们本地maven私服中复制一份mysql驱动,粘贴到wkywalking启动的oap-libs中

(6)启动程序,发现oap-service还是启动失败

 需要在连接mysql数据库连接中添加时区serverTimezone=GMT 

 (7)启动startup.bat,启动程序,skywalking会默认往我们配置的swtest数据库中添加需要的表

 (8)访问接口,skywalking控制台有记录

 重新启动skywalking后,直接刷新控制台页面,之前的数据还是存在的

 5.自定义skywalking链路追踪

如果我们希望对项目中的业务方法,实现链路追踪,方便我们排查问题,可以使用如下的方式:

(1)pom.xml中引入依赖

        <!--skywalking工具类,跟服务安装包版本一致-->
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.5.0</version>
        </dependency>

(2)调用链路要显示具体的方法,在调用的方法中添加注解@Trace

(3)wkywalking控制台调用链路显示类名到接口名的方法

 (4)调用链路中显示返回值,以及参数值信息,使用@Tag或者@Tags

@Tag注解中key=方法名   value=returnedObj   返回值       agr[0] 参数

param标识参数,returnedObj标识返回值

    @RequestMapping("/add")
    @Trace
    @Tag(key = "add",value ="returnedObj")
    public String add() {
        System.out.println("下单成功");
        // String forObject = restTemplate.getForObject("http://localhost:8083/stock/reduct", String.class);
        String forObject = restTemplate.getForObject("http://stock-service/stock/reduct", String.class);
        //int a= 1/0;
        return "add order " + forObject;
    }

    @RequestMapping("/getById/{id}")
    @Trace
    @Tags({@Tag(key = "getById",value ="returnedObj"),
          @Tag(key="param",value = "arg[0]")
    })
    public String getById(@PathVariable("id") Integer id) {
        return "根据id获取信息";
    }

 (5)访问接口后,在追踪中点击方法名

 记录了返回值的key为add,以及返回的value值

 还可以记录参数

 6.性能剖析

skywalking的性能剖析,在根据服务名称、端点名称、以及相应的规则建立了任务列表后,在调用了此任务列表的端点后,skywalking会自动记录,剖析当前端口,生成剖析结果,具体流程如图:

(1)一开始性能剖析菜单是没有内容的,需要添加剖析的接口;点击新建任务创建

 

 (2)sleep接口中睡眠2秒,访问接口,查看skywalking控制台的性能剖析

 选中接口/order/sleep,点击分析展开调用链路

 调用链路展开后可以看到花费时间最久的代码

 7.Skywalking集成日志框架

springboot默认的日志配置:logback-spring.xml

(1)在订单服务的pom.xml中引入依赖

        <!--apm-tooltik-logback-1.x-->
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-logback-1.x</artifactId>
            <version>8.5.0</version>
        </dependency>

(2)在订单服务的resources目录中添加logback-spring.xml配置文件,日志级别使用INFO。

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

    <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>

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

(3)logback-spring.xml中的<Pattern>标签的内容填充值,trace的id配置[%tid]

  <Pattern>%d{-yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} </Pattern>

 程序启动时开始打应trace的id,由于没有访问过接口,所以为N/A

 (4)当访问接口时,控制台会打印输出TID信息

(5)复制打应的tid可以去skywalking控制台中根据追踪id搜素记录

 (6)此时日志板块中还是没有任何记录 

(7)把生成的日志添加到skywalkin控制台:

使用gRPC报告程序可以将收集到的日志转发到skywalking oap服务器上。

①在logback-spring.xml中添加grpc的配置

    <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>

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

logback-spring.xml完整配置:

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

    <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>%d{-yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} </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.mdc.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>

 ②访问接口服务,查看skywalking控制台,此时日志页面出现访问的日志信息,包括程序启动的控制台日志信息,可以点击追踪id查看链路访问情况 

.③若skywalking服务不是部署在本地机器上,则grpc上报需要做而外的配置才能把日志上报上去。

在agent/config目录下有agent.config配置文件,添加日志的grpc配置信息

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
 
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
 
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
 
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

8.skywalking告警

skywalking告警功能在6.x版本中新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中。告警规则的定义分为两部分:

(1)告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。

(2)Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知。

8.1告警规则

skywalking的发行版会默认提供config/alarm-setting.yml文件,里面预先定义了一些常用的告警规则,如下:

①过去3分钟内服务平均响应时间超过1秒

②过去2分钟服务成功率低于80%

③过去3分钟内服务响应时间超过1s的百分比

④服务实例在过去2分钟内平均响应时间超过1s,并且实例名称和正则表示式匹配。

⑤过去2分钟内端点平均响应时间超过1秒。

⑥过去2分钟内数据库访问平均响应时间超过1秒

⑦过去2分钟内端点关系平均响应时间超过1秒

这些预定义的告警规则,打开config/alarm-setting.yml文件即可看到

告警规则配置说明:

.Rule name:规则名称,也是在告警信息中显示的唯一名称,必须以_rule结尾,前缀自定义

.Metrics name:度量名称

.Include names:该规则作用于哪些实体类名称,比如服务名、终端名(可选,默认全部)

.Exclude names:该规则不用于哪些实体名称,比如服务名、终端名(可选,默认为空)

.Threshold:阈值

.OP:操作符,目前支持>、<、=

.Period:多久告警规则需要被核实一下,

.Count:在一个Period窗口中,如果values超过Threshold值(按op),达到count值,则发送警报

 8.2webhook(网络钩子)

webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是web层面的,由于是web层面的,所以当事件发生时,回调的不再是代码中的方法或者函数,而是服务接口。例如在告警这个场景中,告警就是一个事件。当该事件发生时,Skywalking就会自动去调用一个配置好的接口,该接口就是所谓的webhook。

Skywalking的告警消息会通过http请求进行发送,请求方法为post,Content-Type为application/json,其JSON数据是基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>进行序列化的。

官网参考:https://github.com/apache/skywalking/blob/v8.5.0/docs/en/setup/backend/backend-alarm.md

json格式例子:

[{
	"scopeId": 1, 
	"scope": "SERVICE",
	"name": "serviceA", 
	"id0": "12",  
	"id1": "",  
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "alarmMessage xxxx",
	"startTime": 1560524171000
}, {
	"scopeId": 1,
	"scope": "SERVICE",
	"name": "serviceB",
	"id0": "23",
	"id1": "",
    "ruleName": "service_resp_time_rule",
	"alarmMessage": "alarmMessage yyy",
	"startTime": 1560524171000
}]

(1)写接收钩子函数的实体类



/**
 * 警告类实体
 */
public class AlarmMessageEntity {

    private int scopeId;
    private String scope;
    private String name;
    private String id0;
    private String id1;
    private String ruleName;
    private String alarmMessage;
    private List<Tag> tags;
    private long startTime;
    private transient int period;
    private transient boolean onlyAsCondition;




    public int getScopeId() {
        return scopeId;
    }

    public void setScopeId(int scopeId) {
        this.scopeId = scopeId;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId0() {
        return id0;
    }

    public void setId0(String id0) {
        this.id0 = id0;
    }

    public String getId1() {
        return id1;
    }

    public void setId1(String id1) {
        this.id1 = id1;
    }

    public String getRuleName() {
        return ruleName;
    }

    public void setRuleName(String ruleName) {
        this.ruleName = ruleName;
    }

    public String getAlarmMessage() {
        return alarmMessage;
    }

    public void setAlarmMessage(String alarmMessage) {
        this.alarmMessage = alarmMessage;
    }

    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

    public int getPeriod() {
        return period;
    }

    public void setPeriod(int period) {
        this.period = period;
    }

    public boolean isOnlyAsCondition() {
        return onlyAsCondition;
    }

    public void setOnlyAsCondition(boolean onlyAsCondition) {
        this.onlyAsCondition = onlyAsCondition;
    }

    @Override
    public String toString() {
        return "AlarmMessageEntity{" +
                "scopeId=" + scopeId +
                ", scope='" + scope + '\'' +
                ", name='" + name + '\'' +
                ", id0='" + id0 + '\'' +
                ", id1='" + id1 + '\'' +
                ", ruleName='" + ruleName + '\'' +
                ", alarmMessage='" + alarmMessage + '\'' +
                ", tags=" + tags +
                ", startTime=" + startTime +
                ", period=" + period +
                ", onlyAsCondition=" + onlyAsCondition +
                '}';
    }
}

(2)钩子函数调用的后台接口服务,controller控制层,必须使用post方法

@RestController

@RequestMapping("/alarm")
public class AlarmController {

    /**
     * 接收钩子函数的接口,必须使用POST方式,使用实体来接收参数
     * @param list
     */
    @PostMapping(value="/receive")
    public void receive(@RequestBody List<AlarmMessageEntity> list){
        System.out.println("已经接收到告警消息:"+list.get(0).toString());

    }
}

(3)在config/alarm-settings.yml中的webhooks中配置钩子函数

 访问接口告警信息

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba中,可以使用SkyWalking进行链路追踪SkyWalking是一个开源的APM(应用程序性能管理)系统,支持多语言和多框架,包括Java、.NET Core、Node.js等。下面简单介绍如何使用SkyWalking进行链路追踪: 1. 添加依赖 在Spring Boot项目中,需要添加以下依赖: ```xml <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <version>${skywalking.version}</version> </dependency> <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-logback-1.x</artifactId> <version>${skywalking.version}</version> <scope>runtime</scope> </dependency> ``` 其中${skywalking.version}可以根据需要自行指定。 2. 配置SkyWalkingSpring Boot项目中,可以通过application.properties或application.yml配置文件进行配置。以下是一个示例: ```yml # SkyWalking配置 skywalking: # SkyWalking OAP地址 address: 127.0.0.1:11800 # 应用名称 application-name: my-application ``` 其中,address指定了SkyWalking OAP的地址,application-name指定了应用的名称。 3. 启用SkyWalkingSpring Boot项目中,可以通过注解@EnableSkyWalking来启用SkyWalking。例如: ```java @SpringBootApplication @EnableSkyWalking public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 4. 查看链路追踪数据 启动应用后,可以在SkyWalking控制台中查看链路追踪数据。打开浏览器并输入http://localhost:8080进入SkyWalking控制台,查看应用的链路追踪数据。 以上是使用SkyWalking进行链路追踪的基本步骤,具体使用过程中可以根据需要进行配置和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值