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环境搭建部署

Spring cloud alibaba--SkyWalking链路追踪_第1张图片

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

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

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

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

2.1下载skywalking

地址:Downloads | Apache SkyWalking

Spring cloud alibaba--SkyWalking链路追踪_第2张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第3张图片

目录结构:

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

Spring cloud alibaba--SkyWalking链路追踪_第4张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第5张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第6张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第7张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第8张图片

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

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

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

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

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

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

Spring cloud alibaba--SkyWalking链路追踪_第9张图片

⑤agent:

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

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

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

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

Spring cloud alibaba--SkyWalking链路追踪_第10张图片

 2.2启动服务

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

Spring cloud alibaba--SkyWalking链路追踪_第11张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第12张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第13张图片

 2.3访问前端ui页面

 根据webapp/webapp.yml中配置的ui的启动端口,访问ui页面Spring cloud alibaba--SkyWalking链路追踪_第14张图片

 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参数,如下图所示:

Spring cloud alibaba--SkyWalking链路追踪_第15张图片

-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服务。

Spring cloud alibaba--SkyWalking链路追踪_第16张图片

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

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

Spring cloud alibaba--SkyWalking链路追踪_第17张图片

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

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

Spring cloud alibaba--SkyWalking链路追踪_第18张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第19张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第20张图片

3.4接入多个微服务

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

Spring cloud alibaba--SkyWalking链路追踪_第21张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第22张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第23张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第24张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第25张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第26张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第27张图片

 4.Skywalking持久化跟踪数据

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

Spring cloud alibaba--SkyWalking链路追踪_第28张图片

 4.1基于mysql的数据持久化

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

Spring cloud alibaba--SkyWalking链路追踪_第29张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第30张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第31张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第32张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第33张图片

Spring cloud alibaba--SkyWalking链路追踪_第34张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第35张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第36张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第37张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第38张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第39张图片

 5.自定义skywalking链路追踪

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

(1)pom.xml中引入依赖

        
        
            org.apache.skywalking
            apm-toolkit-trace
            8.5.0
        

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

Spring cloud alibaba--SkyWalking链路追踪_第40张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第41张图片 (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)访问接口后,在追踪中点击方法名

Spring cloud alibaba--SkyWalking链路追踪_第42张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第43张图片

 还可以记录参数

Spring cloud alibaba--SkyWalking链路追踪_第44张图片

 6.性能剖析

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

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

Spring cloud alibaba--SkyWalking链路追踪_第45张图片

 Spring cloud alibaba--SkyWalking链路追踪_第46张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第47张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第48张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第49张图片

 7.Skywalking集成日志框架

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

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

        
        
            org.apache.skywalking
            apm-toolkit-logback-1.x
            8.5.0
        

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



    
    

    
        
        
            
                ${CONSOLE_LOG_PATTERN}
            
        
    

    
    
       
    

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

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

 程序启动时开始打应trace的id,由于没有访问过接口,所以为N/ASpring cloud alibaba--SkyWalking链路追踪_第50张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第51张图片

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

Spring cloud alibaba--SkyWalking链路追踪_第52张图片 (6)此时日志板块中还是没有任何记录 

Spring cloud alibaba--SkyWalking链路追踪_第53张图片(7)把生成的日志添加到skywalkin控制台:

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

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

    
        
            
                %d{-yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n 
            
        
    

    
    
        
        
    

logback-spring.xml完整配置:



    
   

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

    
        
            
                %d{-yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n 
            
        
    

    
    
        
        
    

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

Spring cloud alibaba--SkyWalking链路追踪_第54张图片

.③若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文件即可看到

Spring cloud alibaba--SkyWalking链路追踪_第55张图片

告警规则配置说明:

.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进行序列化的。

官网参考: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 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 getTags() {
        return tags;
    }

    public void setTags(List 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 list){
        System.out.println("已经接收到告警消息:"+list.get(0).toString());

    }
}

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

Spring cloud alibaba--SkyWalking链路追踪_第56张图片

 访问接口告警信息

Spring cloud alibaba--SkyWalking链路追踪_第57张图片

Spring cloud alibaba--SkyWalking链路追踪_第58张图片

你可能感兴趣的:(skywalking,spring,cloud,skywalking,spring,cloud,日志,追踪,告警)