您现在的位置是:首页 >其他 >SpringCloud使用SkyWalking实现分布式链路追踪2以及Prometheus全方位监控告警系统网站首页其他

SpringCloud使用SkyWalking实现分布式链路追踪2以及Prometheus全方位监控告警系统

帅得真的是无敌了 2024-06-17 11:28:01
简介SpringCloud使用SkyWalking实现分布式链路追踪2以及Prometheus全方位监控告警系统

一、SkyWalking链路追踪使用Elasticsearch数据库

1、SkyWalking连接Elasticsearch数据库

在前面搭建完linux的elasticsearch环境,以及一部分的skywalking的环境;现在继续处理skywalking的环境。

  1. skywalking9.4.0在启动一次之后,将storage的数据库进行修改后,发现只能打开界面,不能显示数据。
    所以我直接把skywalking安装目录删除了:rm -rf /usr/local/apache-skywalking-apm-bin/
  2. 重新解压缩:tar -zxvf /opt/apache-skywalking-apm-9.4.0.tar.gz -C /usr/local/
  3. 然后修改webapp下的application.yml文件:vim /usr/local/apache-skywalking-apm-bin/webapp/application.yml
    在这里插入图片描述
  4. 编辑skywalking的application.yml配置:vim /usr/local/apache-skywalking-apm-bin/config/application.yml
    在这里插入图片描述
  5. 启动SkyWalking
    1)进入到SkyWalking的bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
    2)启动SkyWalking:./startup.sh
    在这里插入图片描述

2、SkyWalking自定义链路追踪

  1. 在cloud-provider-skywalking-payment8001项目的POM文件中,添加如下数据库依赖

    <!--    数据库驱动    -->
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.32</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.skywalking/apm-toolkit-trace -->
    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-trace</artifactId>
        <version>8.15.0</version>
    </dependency>
    
    <!--数据库连接池 HikariCP-->
    <!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>5.0.1</version>
    </dependency>
    
  2. 在cloud-provider-skywalking-payment8001项目的application.yml文件中,添加如下数据库配置

    spring:
      # 数据库配置
      datasource:
        name: sonice1024
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
        type: com.zaxxer.hikari.HikariDataSource
        hikari:
          minimum-idle: 3
          auto-commit: true
          idle-timeout: 10000
          max-lifetime: 1800000
          connection-timeout: 30000
          connection-test-query: SELECT 1
    

    此时的mysql使用本地,即localhost,而不是linux虚拟机上的。

  3. 打开Navicat,创建连接后,对连接名右键新建数据库test。
    在这里插入图片描述

  4. 在test数据库中创建表和添加数据
    在这里插入图片描述
    1)创建表

    CREATE TABLE user
    (
        id BIGINT(20) NOT NULL COMMENT '主键ID',
        name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
        age INT(11) NULL DEFAULT NULL COMMENT '年龄',
        email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
        PRIMARY KEY (id)
    );
    

    2)添加数据

    INSERT INTO user (id, name, age, email) VALUES
    (1, 'Jone', 18, 'test1@baomidou.com'),
    (2, 'Jack', 20, 'test2@baomidou.com'),
    (3, 'Tom', 28, 'test3@baomidou.com'),
    (4, 'Sandy', 21, 'test4@baomidou.com'),
    (5, 'Billie', 24, 'test5@baomidou.com');
    
  5. 在cloud-provider-skywalking-payment8001项目的com.zzx.entity包下,创建实体类User

    package com.zzx.entity;
    
    import lombok.Data;
    import lombok.ToString;
    
    @Data
    @ToString
    public class User {
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    
  6. 在cloud-provider-skywalking-payment8001项目的com.zzx.mapper包下,创建User的dao层接口UserMapper

    package com.zzx.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.zzx.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }
    
    

    即继承BaseMapper类,传入一个实体类,对应数据库的表,还有加上@Mapper注解。

  7. 在cloud-provider-skywalking-payment8001项目的com.zzx.service包下,创建User的service层接口IUserService

    package com.zzx.service;
    
    import com.zzx.entity.User;
    
    import java.util.List;
    
    public interface IUserService {
        /**
         * 查询全部用户
         * @return
         */
        List<User> getUser();
    
        /**
         * 根据id查询用户
         * @param id
         * @return
         */
        User findById(Long id);
    }
    
    
  8. 在cloud-provider-skywalking-payment8001项目的com.zzx.service.impl包下,创建User的service层实现类UserServiceImpl

    package com.zzx.service.impl;
    
    import com.zzx.entity.User;
    import com.zzx.mapper.UserMapper;
    import com.zzx.service.IUserService;
    import org.apache.skywalking.apm.toolkit.trace.Trace;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    @Service
    public class UserServiceImpl implements IUserService {
        @Autowired
        private UserMapper userMapper;
    
        /**
         * 查询全部用户
         * @return
         */
        @Trace
        @Override
        public List<User> getUser() {
            return userMapper.selectList(null);
        }
        /**
         * 根据用户id查询用户
         * @param id 用户id
         * @return
         */
        @Trace
        @Override
        public User findById(Long id) {
            return userMapper.selectById(id);
        }
    }
    
    
  9. 在cloud-provider-skywalking-payment8001项目的com.zzx.controller包下,创建User的controller层类UserController

    package com.zzx.controller;
    
    import com.zzx.entity.User;
    import com.zzx.service.IUserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    @RequestMapping("user")
    @RestController
    public class UserController {
        @Autowired
        private IUserService iUserService;
    
        /**
         * 查询全部用户
         * @return
         */
        @GetMapping("findByAll")
        public List<User> getUser(){
            return iUserService.getUser();
        }
    
        /**
         * 根据用户id查询用户
         * @param id
         * @return
         */
        @GetMapping("findById")
        public User findById(Long id){
            return iUserService.findById(id);
        }
    
    }
    
    
  10. 测试
    1)启动Eureka7001和Eureka7002以及cloud-provider-skywalking-payment8001项目
    2)启动虚拟机的SkyWalking服务和Elasticsearch服务
    3)浏览器访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    4)浏览器访问:http://192.168.126.11:8068,然后点击导航栏的Trace即可看到刚刚请求的链路信息。
    在这里插入图片描述

3、SkyWalking的调用日志

  1. Skywalking8.4.0版本开始才支持收集日志功能,在cloud-provider-skywalking-payment8001项目的POM添加如下收集日志的依赖。

    <!-- https://mvnrepository.com/artifact/org.apache.skywalking/apm-toolkit-logback-1.x -->
    <dependency>
        <groupId>org.apache.skywalking</groupId>
        <artifactId>apm-toolkit-logback-1.x</artifactId>
        <version>8.11.0</version>
    </dependency>
    
  2. 在cloud-provider-skywalking-payment8001项目的resources目录下,创建logback.xml文件,配置如下

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <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{HH:mm:ss.SSS} [%thread] %-5level logger_name:%logger{36} - [%tid] - message:%msg%n</pattern>
                </layout>
            </encoder>
        </appender>
        <appender name="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="log"/>
        </root>
    
    
    </configuration>
    
    
  3. 在skywalking-agent/config/agent.config配置文件中,添加如下配置:
    在这里插入图片描述

    # 指定要向其报告日志数据的grpc服务器的主机
    plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.126.11}
    
    # 指定要向其报告日志数据的grpc服务器的端口
    plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
    
    # 指定grpc客户端要报告的日志数据的最大大小
    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}
    
  4. 测试
    1)启动Eureka7001和Eureka7002以及cloud-provider-skywalking-payment8001服务
    2)在浏览器上访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    3)此时浏览器访问:http://192.168.126.11:8068,点击导航条的Log,即可出现这个调用的日志。
    在这里插入图片描述

二、SkyWalking链路追踪的告警功能

1、SkyWalking的告警规则

  1. Skywalking默认支持7种通知:
    web、grpc、微信、钉钉、飞书、华为weLink、slack

  2. 默认规则
    Skywalking默认提供的 alarm-settings.yml ,定义的告警规则如下:
    1)过去3分钟内服务平均响应时间超过1秒
    2)服务成功率在过去2分钟内低于80%
    3)服务90%响应时间在过去3分钟内高于1000毫秒
    4)服务实例在过去2分钟内的平均响应时间超过1秒
    5)端点平均响应时间过去2分钟超过1秒

  3. 告警规则
    1)endpoint_percent_rule:规则名称,将会在告警消息体中展示,必须唯一,且以 _rule 结尾
    2)metrics-name:度量名称
    3)include-names:将此规则作用于匹配的实体名称上,实体名称可以是服务名称或端点名称等
    4)exclude-names:将此规则作用于不匹配的实体名称上,实体名称可以是服务名称或端点名称等
    5)threshold:阈值
    6)op:操作符,目前支持 >、<、=
    7)period:多久检测一次告警规则,即检测规则是否满足的时间窗口,与后端开发环境匹配
    8)count:在一个period窗口中,如果实际值超过该数值将触发告警
    9)silence-period:触发告警后,在silence-period这个时间窗口中不告警,该值默认和- – — period相同。例如,在时间T这个瞬间触发了某告警,那么在(T+10)这个时间段,不会再次触发相同告警。
    10)message:告警消息体,{name} 会解析成规则名称

  4. Webhook
    Webhook表达的意思是,当告警发生时,将会请求的地址URL(用POST方法)。警报消息将会以 application/json 格式发送出去。

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

    参数:

    scopeId、scope:作用域
    name:目标作用域下的实体名称;
    id0:作用域下实体的ID,与名称匹配;
    id1:暂不使用;
    ruleName: alarm-settings.yml 中配置的规则名称;
    alarmMessage:告警消息体;
    startTime:告警时间(毫秒),时间戳形式。

2、SkyWalking自定义告警规则

  1. 编辑alarm-settings.yml告警规则文件:vim /usr/local/apache-skywalking-apm-bin/config/alarm-settings.yml,添加如下配置

    service_response_time_rule:
      #指定的规则
      metrics-name: service_resp_time
      op: ">"
      # 阈值
      threshold: 1  # 单位毫秒
      # 多久检查一次当前的指标数据是否符合告警规则
      period: 5
      # 达到多少次告警后,发送告警消息
      count: 1
      # 告警消息内容
      message: 服务{name}最近5分钟以内响应时间超过了1ms
    
    
  2. 重启SkyWalking
    1)将SkyWalking服务杀死
    在这里插入图片描述
    2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
    3)启动SkyWalking服务:./startup.sh

  3. 修改cloud-provider-skywalking-payment8001项目的com.zzx.service.impl包下的UserServiceImpl类的getUser方法

    @Trace
    @Override
    public List<User> getUser() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        return userMapper.selectList(null);
    }
    

    即添加一个休眠1S的代码;从而触发刚刚定义的SkyWalking的告警规则。

  4. 此时UserController也需要进行异常的抛出。

  5. 测试
    1)启动Eureka7001和Eureka7002以及重启cloud-provider-skywalking-payment8001服务
    2)在浏览器上访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    3)此时浏览器访问:http://192.168.126.11:8068,点击左边导航条的告警标志,即可出现这个告警信息。如果没有告警信息,可以多请求几次或者延长休眠时间。在这里插入图片描述

3、SkyWalking实现网络钩子Webhooks

  1. 在父工程cloud下,右键new Module,创建子模块项目cloud-alarm9090
    在这里插入图片描述

  2. 在cloud-alarm9090项目的POM文件中添加如下依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud</artifactId>
            <groupId>com.zzx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-alarm9090</artifactId>
    
        <properties>
            <maven.compiler.source>17</maven.compiler.source>
            <maven.compiler.target>17</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.26</version>
            </dependency>
        </dependencies>
    
    
    </project>
    
  3. 将cloud-alarm9090项目的com.zzx包下的主启动类Main修改为AlarmMain9090 ,代码如下

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @Slf4j
    public class AlarmMain9090 {
        public static void main(String[] args) {
            SpringApplication.run(AlarmMain9090.class,args);
            log.info("******  AlarmMain9090 启动 *****");
        }
    }
    
  4. 在cloud-alarm9090项目的resources目录下创建application.yml文件,配置如下

    server:
      port: 9090
    
  5. 在cloud-alarm9090项目的com.zzx.domain包下,创建接收实体类AlarmMessage,代码如下

    package com.zzx.domain;
    
    
    import lombok.Data;
    import lombok.Getter;
    import lombok.Setter;
    
    import java.util.List;
    
    
    /**
     * Alarm message represents the details of each alarm.
     */
    @Data
    public class AlarmMessage {
        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;
        }
    }
    
    
  6. 在cloud-alarm9090项目的com.zzx.controller包下,创建告警控制层类AlarmController ,代码如下

    package com.zzx.controller;
    
    import com.zzx.domain.AlarmMessage;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * 告警控制层
     */
    @RestController
    @RequestMapping("alarm")
    public class AlarmController {
    
        /**
         * 钩子服务
         */
        @PostMapping("dingding")
        public void message(@RequestBody List<AlarmMessage> alarmMessages){
            StringBuilder builder = new StringBuilder();
            alarmMessages.forEach(info -> {
                builder.append("
    scopeId:").append(info.getScopeId())
                        .append("
    Scope实体:").append(info.getScope())
                        .append("
    告警消息:").append(info.getAlarmMessage())
                        .append("
    告警规则:").append(info.getRuleName())
                        .append("
    
    ------------------------
    
    ");
            });
            System.out.println(builder);
        }
    
    }
    
    
  7. 先从网络适配器的VMnet8中获取到虚拟机在同一个网关下的ip地址,用来配置到下面的告警规则文件alarm-settings.yml中
    在这里插入图片描述

  8. 编辑alarm-settings.yml告警规则文件:vim /usr/local/apache-skywalking-apm-bin/config/alarm-settings.yml,添加如下配置

    webhooks:
    	# 钉钉告警
        - http://192.168.126.1:9090/alarm/dingding
    

    即将告警消息使用Post请求推送到这个地址中。

  9. 重启SkyWalking
    1)将SkyWalking服务杀死
    在这里插入图片描述
    2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
    3)启动SkyWalking服务:./startup.sh

  10. 关闭防火墙
    在这里插入图片描述

  11. 测试
    1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及AlarmMain9090服务
    2)在浏览器上访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    3)AlarmMain9090服务的控制台会打印如下信息
    在这里插入图片描述
    如果没有出现,则多访问几次http://localhost:8001/user/findByAll

4、SkyWalking使用网络钩子Webhooks实现钉钉告警

  1. 创建钉钉群聊,然后在群里的右上角点击设置,选择机器人,再选择添加机器人,再次选择添加机器人,选择自定义(通过Webhook接入自定义服务),再点击添加,按下图进行配置,然后把秘钥复制起来,点击完成即可。最后将网络钩子Webhook的链接和秘钥复制下来放在cloud-alarm9090项目的yml文件中进行配置即可。
    在这里插入图片描述

在这里插入图片描述

  1. 在cloud-alarm9090项目的POM文件中添加如下依赖

    <!--钉钉工具包-->
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>alibaba-dingtalk-service-sdk</artifactId>
       <version>2.0.0</version>
    </dependency>
    
    
  2. 修改cloud-alarm9090项目的com.zzx.controller包下的AlarmController类,代码如下

    package com.zzx.controller;
    
    import com.dingtalk.api.DefaultDingTalkClient;
    import com.dingtalk.api.DingTalkClient;
    import com.dingtalk.api.request.OapiRobotSendRequest;
    import com.dingtalk.api.response.OapiRobotSendResponse;
    import com.zzx.domain.AlarmMessage;
    import org.apache.tomcat.util.codec.binary.Base64;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.*;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.net.URLEncoder;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * 告警控制层
     */
    @RestController
    @RequestMapping("alarm")
    public class AlarmController {
        @Value("${dingding.webhook}")
        private String webhook;
        @Value("${dingding.secret}")
        private String secret;
        /**
         * 钩子服务
         */
        @PostMapping("dingding")
        public void message(@RequestBody List<AlarmMessage> alarmMessages){
            alarmMessages.forEach(info -> {
                try {
                    // 当前时间戳
                    Long timestamp = System.currentTimeMillis();
                    String stringToSign = timestamp + "
    " + secret;
                    /**
                     * Mac算法是带有密钥的消息摘要算法
                     * 初始化HmacMD5摘要算法的密钥产生器
                     */
                    Mac mac = Mac.getInstance("HmacSHA256");
                    // 初始化mac
                    mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
                    // 执行消息摘要
                    byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
                    // 拼接签名
                    String sign = "&timestamp=" + timestamp + "&sign=" + URLEncoder.encode(new String(Base64.encodeBase64(signData,false)), "UTF-8");
                    // 构建钉钉发送客户端工具
                    DingTalkClient client = new DefaultDingTalkClient(webhook + sign);
                    // 设置消息类型
                    OapiRobotSendRequest request = new OapiRobotSendRequest();
                    request.setMsgtype("text");
                    // 设置告警信息
                    OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
                    text.setContent("业务告警:
    " + info.getAlarmMessage());
                    request.setText(text);
                    // 接受人
                    OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
                    at.setAtMobiles(Arrays.asList("所有人"));
                    request.setAt(at);
                    OapiRobotSendResponse response = client.execute(request);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    
    }
    
    

    即修改了message方法,将原本从控制台打印,变成推送消息到第三方钉钉的群聊中。

  3. 修改cloud-alarm9090项目的application.yml,配置如下

    server:
      port: 9090
    dingding:
      # 钉钉网络钩子的地址
      webhook: https://oapi.dingtalk.com/robot/send?access_token=2d5c8bdec15d56f9548bee2713562b57c4d5f1ca35eb45eb45fdcb8ffaae7719
      # 秘钥
      secret: SEC6b75579d66b1fe5e5a73cc2186db61e6499e13e493fe755f6c78219e4ed1eade
    
  4. 关闭防火墙
    在这里插入图片描述

  5. 测试
    1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及重启AlarmMain9090服务
    2)在浏览器上访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    3)钉钉中的群聊机器人就会发送告警信息。
    在这里插入图片描述

5、SkyWalking使用网络钩子Webhooks实现邮件告警

  1. 登录到qq邮箱后,点击设置,再点击账户,往下拉到第二个图的管理服务那里,一点击到第三个图那里,点击生成授权码,手机验证后就会出现授权码。复制该授权码,待会需要配置。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 在cloud-alarm9090项目的POM文件中添加如下支持邮箱的依赖

    <!--   邮箱依赖    -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
       <groupId>javax.mail</groupId>
       <artifactId>mail</artifactId>
       <version>1.4.7</version>
    </dependency>
    
    
  3. 在cloud-alarm9090项目的yml配置文件中,添加如下邮箱配置

    spring:
      mail:
        # 配置 SMTP 服务器地址
        host: smtp.qq.com
        # 指定发送者邮箱
        username: xxx@qq.com
        # 配置密码,刚刚申请到的授权码
        password: gfhxpfnivobmigbj
        # 126邮箱SMTP服务器地址:smtp.126.com,端口号:465或者994
        # 163邮箱SMTP服务器地址:smtp.163.com,端口号:465或者994
        # yeah邮箱SMTP服务器地址:smtp.yeah.net,端口号:465或者994
        # qq邮箱SMTP服务器地址:smtp.qq.com,端口号465587
        # 默认的邮件编码为UTF-8
        default-encoding: UTF-8
        properties:
          mail:
            smtp:
              #需要验证用户名密码
              auth: true
            starttls:
              # 设置为配置SMTP连接的属性。要使用STARTTLS,必须设置以下属性
              enable: true
              required: true
    
  4. 在cloud-alarm9090项目的com.zzx.controller包下的AlarmController类中,添加如下代码

    @Autowired
    private JavaMailSender javaMailSender;
    /**
     * 钩子服务 邮件告警
     */
    @PostMapping("sendMail")
    public void sendMail(@RequestBody List<AlarmMessage> alarmMessages){
        alarmMessages.forEach(info -> {
            //邮件客户端 MimeMailMessage可以携带附件,SimpleMailMessage不能携带附件
            SimpleMailMessage mailMessage = new SimpleMailMessage();
            // 指定发件人的qq邮箱
            mailMessage.setFrom("xxx@qq.com");
            // 指定收件人的邮箱
            mailMessage.setTo("xxx@qq.com");
            // 邮件主题
            mailMessage.setSubject(info.getName());
            // 邮件内容
            mailMessage.setText(info.getAlarmMessage());
            // 发送邮件
            javaMailSender.send(mailMessage);
        });
    }
    
  5. 编辑alarm-settings.yml告警规则文件:vim /usr/local/apache-skywalking-apm-bin/config/alarm-settings.yml,添加如下配置

    webhooks:
    	# 邮件告警
        - http://192.168.126.1:9090/alarm/sendMail
    
  6. 重启SkyWalking
    1)将SkyWalking服务杀死
    在这里插入图片描述
    2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
    3)启动SkyWalking服务:./startup.sh

  7. 测试
    1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及重启AlarmMain9090服务
    2)在浏览器上访问:http://localhost:8001/user/findByAll
    在这里插入图片描述
    3)qq邮箱就会发送消息到指定邮箱
    在这里插入图片描述

三、全方位监控告警系统

1、系统监控报警框架Prometheus以及UI可视化Grafana的概论

  1. Prometheus的具体流程:
    1)Prometheus Server: 用于定时抓取数据指标(metrics)、存储时间序列数据(TSDB)
    2)Jobs/exporte: 收集被监控端数据并暴露指标给Prometheus
    3)Pushgateway :监控端的数据会用push的方式主动传给此组件,随后被Prometheus 服务定时pull此组件数据即可
    4)Alertmanager :报警组件,可以通过邮箱、微信等方式
    5)Web UI :用于多样的UI展示,一般为Grafana
    6)还有一些例如配置自动发现目标的小组件和后端存储组件

  2. Prometheus的特点

    • 多维度数据模型。
    • 灵活的查询语言。
    • 不依赖分布式存储,单个服务器节点是自主的。
    • 通过基于HTTP的pull方式采集时序数据。
    • 可以通过中间网关进行时序数据推送。
    • 通过服务发现或者静态配置来发现目标服务对象。
    • 支持多种多样的图表和界面展示,比如Grafana等。
  3. Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示。Grafana提供了对prometheus的友好支持,各种工具帮助你构建更加炫酷的数据可视化。

  4. Grafana特点

    • 可视化:快速和灵活的客户端图形具有多种选项。面板插件为许多不同的方式可视化指标和日志。
    • 报警:可视化地为最重要的指标定义警报规则。Grafana将持续评估它们,并发送通知。
    • 通知:警报更改状态时,它会发出通知。接收电子邮件通知。
    • 动态仪表盘:使用模板变量创建动态和可重用的仪表板,这些模板变量作为下拉菜单出现在仪表板顶部。
    • 混合数据源:在同一个图中混合不同的数据源!可以根据每个查询指定数据源。这甚至适用于自定义数据源。
    • 注释:注释来自不同数据源图表。将鼠标悬停在事件上可以显示完整的事件元数据和标记。
    • 过滤器:过滤器允许您动态创建新的键/值过滤器,这些过滤器将自动应用于使用该数据源的所有查询。

2、Prometheus服务的环境搭建

  1. Prometheus的linux2.44版本下载地址:https://github.com/prometheus/prometheus/releases/download/v2.44.0-rc.2/prometheus-2.44.0-rc.2.linux-amd64.tar.gz
  2. 将prometheus上传到虚拟机的/opt目录下,在opt目录中进行解压缩到到/usr/local目录中:tar -zxvf prometheus-2.44.0-rc.2.linux-amd64.tar.gz -C /usr/local
  3. 进入到prometheus的安装目录:cd /usr/local/prometheus-2.44.0-rc.2.linux-amd64/
  4. 启动prometheus服务并指定它的配置文件:./prometheus --config.file=prometheus.yml
    默认指定的配置文件就是prometheus.yml;所以此时可以不用指定。
    • 如果此时端口号被占用,先检查9090是哪个进程在占用:lsof -i :9090
      因为prometheus默认端口就是9090
    • 杀死该进程:kill -9 PID号,再启动就可以了
      在这里插入图片描述
  5. 在浏览器上访问:http://192.168.126.11:9090
    在这里插入图片描述
  6. 如果后面需要关闭prometheus服务
    • 先找到prometheus服务的PID号:pgrep -f prometheus
    • 杀死该进程:kill -9 PID号

3、Grafana服务的环境搭建

  1. 因为前面打开了Prometheus服务,直接再打开一个窗口,双击该虚拟机的Session的名字即可打开新窗口。
    在这里插入图片描述
  2. 拉取Grafana的最新镜像:docker pull grafana/grafana-enterprise
  3. 创建并运行容器:docker run -d --name=grafana -p 3000:3000 grafana/grafana-enterprise
  4. 在浏览器中访问:http://192.168.126.11:3000
    Grafana的帐号和密码都是admin
  5. 登陆进去后,按下图步骤点击Data sources,然后点击Add data source,即配置数据源。
    在这里插入图片描述
  6. 再点击Prometheus,即配置Prometheus的数据源,配置如下,然后拉到下面,点击save保存即可
    在这里插入图片描述
    即配置prometheus的服务地址,以及自定义该配置的名字。
  7. 按下图配置Grafana模板,12856是Grafana模板ID。更多模板请参考:https://grafana.com/grafana/dashboards
    在这里插入图片描述
  8. 按下图选择刚刚的配置名,然后点击import即可
    在这里插入图片描述
  9. 然后就会出现下图的DashBoard,即仪表盘
    在这里插入图片描述

4、将微服务应用接入Prometheus服务

  1. 在cloud父工程下,创建一个子模块项目cloud-provider-prometheus-payment8001
    在这里插入图片描述

  2. 在cloud-provider-prometheus-payment8001项目的POM文件中引入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud</artifactId>
            <groupId>com.zzx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-provider-prometheus-payment8001</artifactId>
    
        <properties>
            <maven.compiler.source>17</maven.compiler.source>
            <maven.compiler.target>17</maven.compiler.target>
        </properties>
        <dependencies>
            <!--  引入Eureka client依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- actuator监控信息完善 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <!--    prometheus依赖    -->
            <dependency>
                <groupId>io.micrometer</groupId>
                <artifactId>micrometer-registry-prometheus</artifactId>
                <version>1.10.5</version>
            </dependency>
    
        </dependencies>
    
    </project>
    
  3. 在cloud-provider-prometheus-payment8001项目的resources目录下,创建application.yml文件,配置如下

    server:
      port: 8001
    eureka:
      instance:
        # 注册名
        instance-id: cloud-provider-payment8001
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    spring:
      application:
        #设置应用名
        name: cloud-payment-provider
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'
      endpoint:
        health:
          show-details: ALWAYS
      metrics:
        tags:
          application: ${spring.application.name}
    
    

    management.endpoints.web.exposure.include=* 配置为开启 Actuator 服务。

  4. 将cloud-provider-payment8001项目的com.zzx.controller包以及它的主启动类PaymentMain8001复制到cloud-provider-prometheus-payment8001项目中
    在这里插入图片描述

  5. cloud-provider-prometheus-payment8001项目中的com.zzx包下的PaymentMain8001主启动类修改为PaymentPrometheusMain8001,代码如下

    package com.zzx;
    
    import io.micrometer.core.instrument.MeterRegistry;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    
    /**
     * 主启动类
     */
    @SpringBootApplication
    @Slf4j
    public class PaymentPrometheusMain8001 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentPrometheusMain8001.class,args);
            log.info("****** PaymentPrometheusMain8001 服务启动成功 *****");
        }
        @Bean
        MeterRegistryCustomizer<MeterRegistry> configurer(@Value("${spring.application.name}") String applicationName) {
            return registry -> registry.config().commonTags("application", applicationName);
        }
    }
    
    
  6. 修改prometheus服务的prometheus.yml配置文件
    1)关闭prometheus服务,直接在prometheus服务的窗口按crtrl + c,中断该服务
    2)修改prometheus.yml配置文件:vim /usr/local/prometheus-2.44.0-rc.2.linux-amd64/prometheus.yml,添加如下配置

    - job_name: "cloud-provider-prometheus-payment8001"
      scrape_interval: 5s
      metrics_path: "/actuator/prometheus"
      static_configs:
        - targets: ["192.168.126.1:8001"]
    
    

    此时的192.168.126.1是从网络适配器的VMnet8的ipv4中的。
    在这里插入图片描述
    3)启动Prometheus服务:./prometheus

  7. 浏览器访问:http://192.168.126.11:9090,然后点击Status,选择到targets。
    在这里插入图片描述
    如果cloud-provider-prometheus-payment8001的状态显示up,证明暴露指标成功

  8. 浏览器访问:http://192.168.126.11:3000/dashboards,然后选择刚刚的界面,能出现下图即可。
    在这里插入图片描述

总结

  1. SkyWalking官方推荐使用Elasticsearch数据库。
    1)SkyWalking连接Elasticsearch数据库,需要在SkyWalking安装目录的config/application.yml文件中的storage属性中进行配置。skywalking9.4.0有个坑,就是你在启动SkyWalking后,再去切换数据库,再次启动时,会出现不显示数据的问题。需要重新安装,然后在配置完成后,再去启动SkyWalking服务即可。
    2)SkyWalking自定义链路追踪,需要在追踪的方法上加上@Trace注解。然后SkyWalking服务就会对该方法从开始到结束的所有操作进行追踪。
  2. 1)SkyWalking的调用日志,需要在POM文件中,引入收集日志的依赖;然后需要在resources下创建一个logback.xml配置文件;最后在JavaAgent中配置SkyWalking服务主机的ip和端口号等信息;这样就可以将SkyWalking收集到的日志信息上传到SkyWalking中。
    2)Skywalking发送告警的基本原理是每隔一段时间轮询Skywalking-collector收集到的链路追踪的数据。Skywalking告警可以支持第三方应用,即将告警信息推送到第三方应用。
    3)SkyWalking自定义告警信息,需要在SkyWalking的安装目录下的config目录的alarm-settings.yml告警规则文件中进行添加自定义告警规则。然后重启SkyWalking服务即可。
  3. 1)Webhook可以简单理解为是一种Web层面的回调机制。
    SkyWalking实现网络钩子Webhooks,需要先在alarm-settings.yml告警规则文件中指定回调的地址,该地址ip为VMnet8中IPV4中的ip,也就是虚拟机在同一个网关下的ip地址。定义AlarmMessage实体类用来接收SkyWalking使用POST请求传递过来的消息;最后在AlarmController控制层类中定义这个回调的方法,获取到告警消息,然后对该消息进行一个处理即可。
    2)SkyWalking使用网络钩子Webhooks实现钉钉告警,需要创建钉钉中的群聊,添加一个群里的自定义机器人,获取到加密的秘钥(也可以选择不加密)以及获取到webhooks的地址链接配置到application.yml文件中。然后需要引入钉钉告警的依赖;该Controller类中定义这两个变量,这两个变量从刚刚在yml文件中配置两个属性中获取值。最后需要在alarm-settings.yml告警规则文件中进行添加回调方法的请求路径,在对应方法中实现这个钉钉告警。
    3)SkyWalking使用网络钩子Webhooks实现qq邮箱告警,需要先从qq邮箱获取到授权码,然后配置到application.yml文件中,以及在application.yml文件中配置一些支持qq邮箱的配置等。
    然后引入支持邮箱的依赖,最后需要在alarm-settings.yml告警规则文件中进行添加回调方法的请求路径,在对应方法中实现这个邮箱告警即可。
  4. 1)Prometheus 是一套开源的系统监控报警框架。全方位的监控告警系统主要作用是监控微服务运行状况。Grafana提供了对prometheus的友好支持,各种工具帮助你构建更加炫酷的数据可视化。
    2)微服务应用接入Prometheus服务,再由Grafana服务进行页面展示。先手需要Grafana服务中配置Prometheus服务;然后引入micrometer-registry-prometheus等依赖;然后在application.yml配置文件中开启Actuator服务以及指定它的应用名给Grafana等;在主启动类中实现暴露指标到prometheus服务的方法;在虚拟机中修改prometheus安装目录的prometheus.yml配置文件,设置获取应用指标的配置即可。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。