SkyWalking基础知识

SkyWalking

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

官网地址: https://skywalking.apache.org/

下载地址:http://skywalking.apache.org/downloads/

Github地址:https://github.com/apache/skywalking

文档地址: https://skyapm.github.io/document-cn-translation-of-skywalking/

SkyWalking优点:

  • 接入段无代码入侵(字节码增强)
  • 支持java/.net/Node.js/php/go等语言
  • 调用链路可视化,聚合报表较丰富
  • 探针(JavaAgent)对吞吐量影响较小

SkyWalking主要功能:

  • 多种监控手段,可以通过语言探针(JavaAgent)和service mesh获得监控的数据
  • 支持多种语言自动探针,包括 Java,.NET Core 和 Node.JS
  • 轻量高效,无需大数据平台和大量的服务器资源
  • 模块化,UI、存储、集群管理都有多种机制可选
  • 支持告警
  • 优秀的可视化解决方案

SkyWalking环境部署搭建

SkyWalking组成部分如下,其中skywalking oapservice集群和SkyWalking webapp UI服务在一个资源中,部署起来也是相对简单。

在这里插入图片描述

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

搭建SkyWalking OAP服务

下载资源

下载地址

选择合适的版本下载解压即可。(我这边使用的是v9.2.0)

在这里插入图片描述

启动服务

启动前建议修改SkyWalking-web-UI的默认端口8080(8080经常被其他程序占用),此处修改为8868端口。

修改路径为apache-skywalking-apm-bin\webapp\webapp.yml

启动apache-skywalking-apm-bin\bin\startup.bat(linux下启动startup.sh)

在这里插入图片描述

没有日志实时输出,在apache-skywalking-apm-bin\logs下查看启动日志。

启动后会后两个服务,一个是SkyWalking-oap-server,一个是SkyWalking-web-ui。SkyWalking-oap-server服务启动后会暴露11800和12800两个端口(端口可以在apache-skywalking-apm-bin\config\application.yml中修改),11800负责收集监控数据,12800负责接受前端请求。

访问UI

访问http://127.0.0.1:8868/

在这里插入图片描述

SkyWalking接入微服务

下载Java Agent

下载地址

我这边选择的是最新版v8.13.0。下载完成后解压出来即可。

在这里插入图片描述

win下整合SkyWalking

在需要整合SkyWalking的服务中添加参数,在IDEA中添加VM参数。linux下也是一样的使用java -jar带下面的参数运行。

-javaagent:D:\develop\skywalking\skywalking-agent\skywalking-agent.jar
-DSW_AGENT_NAME=skywalking-demo
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800

参数说明:

-javaagent:skywalking-agent.jar在本地磁盘的路径,必须是本地

-DSW_AGENT_NAM:在SkyWalking上显示的服务名

-DSW_AGENT_COLLECTOR_BACKEND_SERVICES:SkyWalking的collector服务的IP和端口,负责收集监控数据的端口

在这里插入图片描述

启动项目,请求一个接口,查看控制台。

在这里插入图片描述

在这里插入图片描述

整合了多个服务的效果(在需要整合的服务中添加对应的参数),调用链路就很清晰了。整合Gateway时需要注意添加plugin插件。

在这里插入图片描述

在这里插入图片描述

Linux下整合SkyWalking

准备一个springboot程序,打成可执行的jar包,写一个shell脚本。在shell脚本上通过设置相关参数启动项目。

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/agent/skywalking‐agent.jar
java $JAVA_AGENT ‐jar springboot‐skywalking‐demo‐0.0.1‐SNAPSHOT.jar #jar启动

上面的脚本和在IDEA中启动写的vm参数是等价的。

SkyWalking持久化到MySQL

SkyWalking默认使用H2数据库存储,H2是一个基于内存的数据库,重启后数据就没有了。虽然SkyWalking监控数据是一个实时的,但运行时间长了内存容易满,就需要重启SkyWalking服务了。如果配置为持久化的数据库中(当然SkyWalking配合ES性能是最好),我们定期的进行数据清理即可,避免了频繁的重启服务。

  • 修改配置
    修改apache-skywalking-apm-bin\config\application.yml文件

在这里插入图片描述

  • 添加mysql驱动
    向apache-skywalking-apm-bin\oap-libs目录下添加MySQL数据库对应的连接驱动包
    在这里插入图片描述

  • 创建数据库
    在数据库中创建apache-skywalking-apm-bin\config\application.yml中的数据库。
    在这里插入图片描述

  • 启动服务

    双击apache-skywalking-apm-bin\bin\startup.bat。
    启动服务后swtest中就会建好很多的表。
    在这里插入图片描述

  • 验证
    重启SkyWalking服务之后,之前的报错依然存在。
    在这里插入图片描述

自定义链路追踪

SkyWalking默认是会记录接口资源(也就是controller层)的链路,当我们希望对项目中的业务方法实现链路追踪,方便我们排查问题时,可以自定义链路追踪。

  • 导入依赖

    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-trace</artifactId>
        <version>8.5.0</version>
    </dependency>
    
  • 添加追踪注解
    在需要加入追踪的业务方法上添加@Trace注解

    @Trace
    public List<Order> all() throws InterruptedException {
        TimeUnit.SECONDS.sleep(2);
        return orderMapper.selectAll();
    }
    

在这里插入图片描述

  • 获取入参和返回值
    添加追踪业务方法@Trace注解的基础上,使用@Tags和@Tag获取入参和返回值

    @Trace
    @Tag(key="all",value="returnedObj")
    public List<Order> all() throws InterruptedException {
        TimeUnit.SECONDS.sleep(2);
        return orderMapper.selectAll();
    }
    
    @Trace
    @Tags({@Tag(key="get",value="returnedObj"),// "returnedObj"为返回值的固定写法,返回值类型需要重写toString方法
           @Tag(key="get",value="arg[0]")}) // "arg[0]" 代表第一个入参参数
    public Order get(Integer id) {
        return orderMapper.selectByPrimaryKey(id);
    }
    

在这里插入图片描述

集成日志

logback官方配置链接

  • 导入依赖

    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-logback-1.x</artifactId>
        <version>{project.release.version}</version>
    </dependency>
    
  • 添加配置文件
    在项目resource下添加logback-spring.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <!-- 引入 Spring Boot 默认的 logback XML 配置文件  -->
        <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    
    
        <!--配置的是控制台日志输出,核心是获取TID追踪ID-->
        <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>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}</Pattern>
                </layout>
            </encoder>
    
        </appender>
    
        <!--配置的是SkyWalking中的日志,可以在SkyWalking UI中直接查看日志-->
        <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"/> <!--同步日志到SkyWalking UI中-->
        </root>
    
    </configuration>
    
  • 修改配置文件
    在skywalking-agent\config\agent.config文件最后添加以下配置

    #  指定要向其报告日志数据的grpc服务器的主机,也就是SkyWalking OAP服务主机地址
    plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
    #  SkyWalking OAP收集数据的端口,默认11800
    plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
    #  日志信息最大size
    plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
    #  数据上报超时时间,单位 S
    plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}
    
  • 启动项目和SkyWalking服务
    控制台输出TID,可以使用TID去SkyWalking UI中查询相关信息。

在这里插入图片描述

SkyWalking UI界面中可以直接查看日志信息。

在这里插入图片描述

告警

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

  1. 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件
  2. Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知
告警规则

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

  1. 过去 3 分钟内服务平均响应时间超过 1 秒
  2. 过去 2 分钟服务成功率低于80%
  3. 过去 3 分钟内服务响应时间超过 1s 的百分比
  4. 服务实例在过去 2 分钟内平均响应时间超过 1s,并且实例名称与正则表达式匹配
  5. 过去 2 分钟内端点平均响应时间超过 1 秒
  6. 过去 2 分钟内数据库访问平均响应时间超过 1 秒
  7. 过去 2 分钟内端点关系平均响应时间超过 1 秒

这些预定义的告警规则,打开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:告警时间,格式为时间戳
告警实现发送邮件
  1. 导入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    
  2. 添加发送邮件配置

    spring:
      # 邮箱配置
      mail:
        host: smtp.163.com
        #发送者邮箱账号
        username: 发送者邮箱账号
        #发送者密钥 POP3
        password: 发送者密钥
        default‐encoding: UTF-8
        port: 465 #端口号465或587
        protocol: smtps
        properties:
         mail:
         debug: false
         smtp:
         socketFactory:
          class: javax.net.ssl.SSLSocketFactory
    
  3. 提供告警接口

    @Slf4j
    @RestController
    @RequiredArgsConstructor
    @RequestMapping("/alarm")
    public class SwAlarmController {
    
        private final JavaMailSender sender;
    
        @Value("${spring.mail.username}")
        private String from;
    
    
        /**
         * 接收skywalking服务的告警通知并发送至邮箱
         *
         * 必须是post
         */
        @PostMapping("/receive")
        public void receive(@RequestBody List<SwAlarmDto> alarmList) {
            SimpleMailMessage message = new SimpleMailMessage();
            // 发送者邮箱
            message.setFrom(from);
            // 接收者邮箱
            message.setTo(from);
            // 主题
            message.setSubject("告警邮件");
            String content = getContent(alarmList);
            // 邮件内容
            message.setText(content);
            sender.send(message);
            log.info("告警邮件已发送..."+content);
        }
    
        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();
        }
    
    }
    

    DTO

    @Data
    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;
    
    
        @Data
        public static class Tag{
            private String key;
            private String value;
        }
    
    }
    
  4. 添加Webhook调用的接口
    修改apache-skywalking-apm-bin\config\alarm-settings.yml中的webhooks配置。接口为上一步编写的接口。

    webhooks:
      - http://127.0.0.1:8088/alarm/receive
    

启动项目和Skywalking服务,在任意一个接口中睡眠两秒,请求几次该接口。就可以收到告警的短信了。

我这边在all接口中睡眠了2秒,调用all接口几次,触发告警。收到邮件。

在这里插入图片描述

告警邮件

在这里插入图片描述

SkyWalking集群

SkyWalking OAP一般都是以集群的方式出现的。那么实现SkyWalking集群是将SkyWalking OAP作为一个服务注册到nacos上,只要SkyWalking OAP服务没有全部宕机,保证有一个SkyWalking OAP在运行,就能进行跟踪。

  • 修改cluster方式
    修改apache-skywalking-apm-bin\config\application.yml文件中的cluster方式为nacos。
    在这里插入图片描述

  • 配置SkyWalking UI服务访问的地址
    修改apache-skywalking-apm-bin\webapp\webapp.yml文件,在oap-service下添加oap服务列表。
    在这里插入图片描述

  • 启动服务
    启动时和单机的相同,需要将所有的OAP服务加入到参数中,多个使用英文逗号隔开。
    startup.sh

     #!/bin/sh
     # SkyWalking Agent配置
    export SW_AGENT_NAME=springboot‐skywalking‐demo
    export SW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.2.7:11800,192.168.2.8:11800,192.168.2.9:11800 # 多个使用英文逗号隔开
    export SW_AGENT_SPAN_LIMIT=2000
    export JAVA_AGENT=‐javaagent:/usr/local/soft/apache‐skywalking‐apm‐bin/agent/skywalking‐agent.jar
    java $JAVA_AGENT ‐jar springboot‐skywalking‐demo‐0.0.1‐SNAPSHOT.jar
    
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值