Spring Cloud Alibaba 微服务组件 Skywalking 分布式任务链(十一)

   Spring Cloud Aibaba 学习目录

1. Spring Cloud Alibaba 微服务介绍(一)

2. Spring Cloud Alibaba 之Nacos 安装(二)

3. Spring Cloud Alibaba 微服务组件 Nacos 注册中心(三)

4. Spring Cloud Alibaba 微服务负载均衡 Ribbon(四)

5. Spring Cloud Alibaba 微服务整合 OpenFeign(五)

6. Spring Cloud Alibaba 微服务组件 Nacos 配置中心(六)

7. Spring Cloud Alibaba 微服务组件 Sentinel 服务保护(七)

8. Spring Cloud Alibaba 分布式事务概念(八)

9. Spring Cloud Alibaba 微服务组件 Seata 分布式事务(九)

10. Spring Cloud Alibaba 服务网关 Gateway(十)

11. Spring Cloud Alibaba 微服务组件 Skywalking 分布式任务链(十一)

语雀文档:Spring Cloud Aibaba 学习 · 语雀


链路追踪介绍

对于一个大型的几十个、几百个微服务构成的微服务架构系统,通常会遇到下面一些问题,比如:

  1. 如何串联整个调用链路,快速定位问题?
  2. 如何缕清各个微服务之间的依赖关系?
  3. 如何进行各个微服务接口的性能分折?
  4. 如何跟踪整个业务流程的调用处理顺序?

Skywalking 是什么

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

链路追踪框架对比

1. Zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单。

2. Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能强大,接入端无代码侵入。

3. Skywalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。

4. CAT是大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具。

性能对比

模拟了三种并发用户:500,750,1000。使用 jmeter 测试,每个线程发送30个请求,设置思考时间为10ms。使用的采样率为1,即100%,这边与生产可能有差别。pinpoint默认的采样率为20,即50%,通过设置agent的配置文件改为100%。zipkin默认也是1。组合起来,一共有12种。下面看下汇总表:

从上表可以看出,在三种链路监控组件中,skywalking的探针对吞吐量的影响最小,zipkin的吞吐量居中。pinpoint的探针对吞吐量的影响较为明显,在500并发用户时,测试服务的吞吐量从1385降低到774,影响很大。然后再看下CPU和memory的影响,在内部服务器进行的压测,对CPU和memory的影响都差不多在10%之内。

 Skywalking 主要功能特性

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

2、支持多种语言自动探针,包括 Java,.NET Core 和 Node.JS;

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

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

5、支持告警;

6、优秀的可视化解决方案;

架构

SkyWalking 逻辑上分为四部分: 探针, 平台后端, 存储和用户界面.

  • 探针 基于不同的来源可能是不一样的, 但作用都是收集数据, 将数据格式化为 SkyWalking 适用的格式.
  • 平台后端, 支持数据聚合, 数据分析以及驱动数据流从探针到用户界面的流程。分析包括 Skywalking 原生追踪和性能指标以及第三方来源,包括 Istio 及 Envoy telemetry , Zipkin 追踪格式化等。 你甚至可以使用 Observability Analysis Language 对原生度量指标用于扩展度量的计量系统 自定义聚合分析。
  • 存储 通过开放的插件化的接口存放 SkyWalking 数据. 你可以选择一个既有的存储系统, ElasticSearch, H2 或 MySQL 集群(Sharding-Sphere 管理),也可以选择自己实现一个存储系统. 当然, 我们非常欢迎你贡献新的存储系统实现。
  • UI 一个基于接口高度定制化的Web系统,用户可以可视化查看和管理 SkyWalking 数据。

SkyWalking 环境搭建部署

  • skywalking agent 和业务系统绑定在一起,负责收集各种监控数据。
  • Skywalking oapservice 是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中。
  • 接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapservice通常以 集群的形式存在。
  • skywalking webapp,前端界面,用于展示数据。
  • 用于存储监控数据的数据库,比如mysql、elasticsearch等。

下载 SkyWalking

下载 : Downloads | Apache SkyWalking

版本目录地址:Index of /dist/skywalking

目录结构

 搭建SkyWalking OAP 服务

启动脚本 bin/startup.sh

日志信息存储在logs目录

启动成功后会有两个应用程序

启动成功后会启动两个服务,

  • 一个是 skywalking-oap-server
  • 一个是 skywalking-web-ui  : 8868

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

skywalking-web-ui 服务会占用 8080 端口, 修改端口可以修改webapp/webapp.yml

server.port:SkyWalking UI服务端口,默认是8080;

collector.ribbon.listOfServers:SkyWalking OAP服务地址数组,SkyWalking UI界面的数据是通过请求SkyWalking OAP服务来获得;

访问:http://127.0.0.1:8080/

页面的右下角可以中英文切换,可以切换选择要展示的时间区间的跟踪数据。

SkyWalking中三个概念

服务(Service) : 表示对请求提供相同行为的一系列或一组工作负载,在使用Agent时,可以定义服务的名字;

服务实例(Service Instance) : 上述的一组工作负载中的每一个工作负载称为一个实例, 一个服务实例实际就是操作系统上的一个真实进程;

端点(Endpoint) : 对于特定服务所接收的请求路径, 如HTTP的URI路径和gRPC服务的类名 + 方法签名;


SkyWalking 接入微服务

 linux 环境—通过 jar 包方式接入

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

startup.sh 启动

#!/bin/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启动

jar 启动

java ‐javaagent:/usr/local/soft/apache‐skywalking‐apm‐bin‐es7/agent/skywalking‐agent.jar
‐DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
‐DSW_AGENT_NAME=springboot‐skywalking‐demo ‐jar springboot‐skywalking‐demo‐0.0.1‐SNAPSHOT.jar

windos 环境—在IDEA中使用 Skywalking

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

说明 -DSW_AGENT_COLLECTOR_BACKEND_SERVICES   可以指定远程地址, 

但是-javaagent必须绑定你本机物理路径的skywalking-agent.jar

# skywalking‐agent.jar的本地磁盘的路径
-javaagent:D:\apache\apache‐skywalking‐apm‐es7‐8.4.0\apache‐skywalking‐apm‐bin‐es7\agent\skywalking‐agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=springboot‐skywalking‐demo
# skywalking的collector服务的IP及端口
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.100:11800

效果图如下

报错调试

http://127.0.0.1:8720/getUserOrder?userId=0

查看报错信息


 
 

Skywalking持久化跟踪数据

默认使用的H2数据库存储(本地存储)

config/application.yml

解决 gateway 服务不能注册

把 agent/ optional-plugins 目录下的gateway插件拷贝到 agent/ plugins目录

Linux 环境

windows 环境

重新启动 skywalking

基于mysql持久化

1. 修改 config目录下的application.yml, 使用mysql作为持久化存储的仓库

2.修改mysql连接配置

注意:需要添加mysql数据驱动包,因为在lib目录下是没有mysql数据驱动包的,所以修改完配置启动是会报错,启动失败的。

添加mysql数据驱动包到oap-libs目录下

启动Skywalking

查看swtest数据库,可以看到生成了很多表

说明启动成功了,打开配置对应的地址http://192.168.3.100:8080/,可以看到skywalking的web界面。

测试:重启skywalking,验证跟踪数据会不会丢失


自定义 SkyWalking 链路追踪

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

引入依赖

<dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-trace</artifactId>
            <version>8.4.0</version>
            <scope>provided</scope>
</dependency>

@Trace将方法加入追踪链路

如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可

测试

加入@Tags或@Tag

我们还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。实现方式:在方法上增加 @Tag 或者@Tags。@Tag 注解中   key  = 方法名   ; value =   returnedObj    返回值   arg[0] 参数

@Trace
@Tag(key = "list", value = "returnedObj")
public List<User> list(){
  return userMapper.list();
 }

@Trace
@Tags({@Tag(key = "param", value = "arg[0]"),
@Tag(key = "user", value = "returnedObj")})
public User getById(Integer id){
  return userMapper.getById(id);
 }


性能分析

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


Skywalking 集成日志框架

logback官方配置

引入依赖

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

添加logback-spring.xml文件

并配置 %tid 占位符

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

控制台日志输出

gRPC报告程序可以将收集到的日志转发到SkyWalking OAP服务器上

logback-spring.xml 中添加

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

打开agent/config/agent.config配置文件, 添加如下配置信息:

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.3.100}
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}

以上配置是默认配置信息,agent与oap在本地的可以不配

配置名

解释

默认值

plugin.toolkit.log.transmit_formatted

是否以格式化或未格式化的格式传输记录的数据

true

plugin.toolkit.log.grpc.reporter.server_host

指定要向其报告日志数据的grpc服务器的主机

127.0.0.1

plugin.toolkit.log.grpc.reporter.server_port

指定要向其报告日志数据的grpc服务器的端口

11800

plugin.toolkit.log.grpc.reporter.max_message_size

指定grpc客户端要报告的日志数据的最大大小

10485760

plugin.toolkit.log.grpc.reporter.upstream_timeout

客户端向上游发送数据时将超时多长时间。单位是秒

30

Skywalking UI效果


SkyWalking 告警功能

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

义分为两部分:

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

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

告警规则

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

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

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

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

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

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

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

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

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

告警规则配置项的说明:

  • Rule name:规则名称,也是在告警信息中显示的唯一名称。必须以_rule结尾,前缀可自定义
  • Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script
  • Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
  • Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为空)
  • Threshold:阈值
  • OP: 操作符,目前支持 >、<、=
  • Period:多久告警规则需要被核实一下。这是一个时间窗口,与后端部署环境时间相匹配
  • Count:在一个Period窗口中,如果values超过Threshold值(按op),达到Count值,需要发送警报
  • Silence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。 默认情况下,它和Period一样,这意味着相同的告警(在同一个Metrics name拥有相同的Id)在同一个Period内只会触发一次
  • message:告警消息

Webhook(网络钩子)

Webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件。当该事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。SkyWalking的告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,其JSON 数据实基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage进行序列化的。

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

字段说明:

scopeId、scope:所有可用的 Scope 详见 org.apache.skywalking.oap.server.core.source.DefaultScopeDefine

name:目标 Scope 的实体名称

id0:Scope 实体的 ID

id1:保留字段,目前暂未使用

ruleName:告警规则名称

alarmMessage:告警消息内容

startTime:告警时间,格式为时间戳


邮件告警功能实践

根据以上两个小节的介绍,可以得知:SkyWalking是不支持直接向邮箱、短信等服务发送告警信息的,SkyWalking只会在发生告警时将告警信息发送至配置好的Webhook接口。

但我们总不能人工盯着该接口的日志信息来得知服务是否发生了告警,因此我们需要在该接口里实现发送邮件或短信等功能,从而达到个性化的告警通知。

接下来开始动手实践,这里基于Spring Boot进行实现。首先是添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐mail</artifactId>
</dependency>

配置邮箱服务:

server:
  ## 启动端口
  port: 8720

spring:
  application:
    ## 注册服务名
    name: skywalking-account
  cloud:
    nacos:
      ## 注册中心地址
      discovery:
        server-addr: 127.0.0.1:8848

  main:
    allow-bean-definition-overriding: true
## 邮箱配置 ##
  mail:
    from: 发送邮箱@163.com
    host: smtp.163.com
    password: 你的邮箱服务密钥
    username: 你的邮箱@163.com
#    port: 465 # 端口号465或587
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true

定义 SkyWalking

根据Skywalking发送的JSON数据定义一个DTO,用于接口接收数据:

/**
 * Alarm message represents the details of each alarm.
 */
@Setter
@Getter
public class SwAlarmDTO {
    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;
}

接着定义一个接口,实现接收SkyWalking的告警通知,并将数据发送至邮箱:

/**
     * 接收skywalking服务的告警通知并发送至邮箱
     *
     * 必须是post
     */
    @PostMapping("/receive")
    public void receive(@RequestBody List<SwAlarmDTO> alarmList) {
        String content = getContent(alarmList);
        Mail mail = new Mail();
        mail.setTo("865391093@qq.com");
        mail.setTitle("服务接口时间超时");
        mail.setContent(content);
        mail.setMsgId(System.currentTimeMillis()+"");

        new Thread(()->{
            mailUtil.send(mail);
            log.info("告警邮件已发送..."+content);
        }).start();
    }

    private String getContent(List<SwAlarmDTO> alarmList) {
        StringBuilder sb = new StringBuilder();
        for (SwAlarmDTO dto : alarmList) {
            sb.append("scopeId: ").append(dto.getScopeId())
                    .append("\nscope: ").append(dto.getScope())
                    .append("\n目标 Scope 的实体名称: ").append(dto.getName())
                    .append("\nScope 实体的 ID: ").append(dto.getId0())
                    .append("\nid1: ").append(dto.getId1())
                    .append("\n告警规则名称: ").append(dto.getRuleName())
                    .append("\n告警消息内容: ").append(dto.getAlarmMessage())
                    .append("\n告警时间: ").append(dto.getStartTime())
                    .append("\n标签: ").append(dto.getTags())
                    .append("\n\n---------------\n\n");
        }
        return sb.toString();
    }

配置 config/alarm-settings.yml文件

最后将该接口配置到SkyWalking中,Webhook的配置位于config/alarm-settings.yml文件的末尾,

格式为http://{ip}:{port}/{uri}。如下示例:

测试告警功能

完成告警接口的开发及配置后,我们来进行一个简单的测试。这里有一条调用链路如下:

我在/producer接口中增加了一行睡2秒的代码:

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

 http://localhost:8072/order/all

执行完测试代码,等待约两分钟后,告警接口的控制台输出了一段日志信息:


Skywalking高可用

概述

在大多数生产环境中,后端应用需要支持高吞吐量并且支持高可用来保证服务的稳定,所以你始终需要在生产环境进行集群管理。

集群方式

Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行跟踪。

搭建一个skywalking oap集群需要:

  • 至少一个Nacos(也可以是nacos集群)
  • 至少一个ElasticSearch/mysql(也可以是es/msql集群)
  • 至少2个skywalking oap服务;
  • 至少1个UI(UI也可以集群多个,用Nginx代理统一入口)

修改配置文件

修改config/application.yml文件

使用nacos作为注册中心

修改nacos配置

 可以选择性修改监听端口

修改存储策略

使用elasticsearch7作为storage


  项目地址https://gitee.com/gaibianzlp/springcould-alibaba-example.githttps://gitee.com/gaibianzlp/springcould-alibaba-example.giticon-default.png?t=LA92https://gitee.com/gaibianzlp/springcould-alibaba-example.git点关注不迷路,觉得对你有帮助请给一个赞或者长按一键三连,谢谢!

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值