文章目录
- 一、SkyWalking链路追踪使用Elasticsearch数据库
- 1、SkyWalking连接Elasticsearch数据库
- 2、SkyWalking自定义链路追踪
- 3、SkyWalking的调用日志
- 二、SkyWalking链路追踪的告警功能
- 1、SkyWalking的告警规则
- 2、SkyWalking自定义告警规则
- 3、SkyWalking实现网络钩子Webhooks
- 4、SkyWalking使用网络钩子Webhooks实现钉钉告警
- 5、SkyWalking使用网络钩子Webhooks实现邮件告警
- 三、全方位监控告警系统
- 1、系统监控报警框架Prometheus以及UI可视化Grafana的概论
- 2、Prometheus服务的环境搭建
- 3、Grafana服务的环境搭建
- 4、将微服务应用接入Prometheus服务
- 总结
一、SkyWalking链路追踪使用Elasticsearch数据库
1、SkyWalking连接Elasticsearch数据库
在前面搭建完linux的elasticsearch环境,以及一部分的skywalking的环境;现在继续处理skywalking的环境。
- skywalking9.4.0在启动一次之后,将storage的数据库进行修改后,发现只能打开界面,不能显示数据。
所以我直接把skywalking安装目录删除了:rm -rf /usr/local/apache-skywalking-apm-bin/
- 重新解压缩:
tar -zxvf /opt/apache-skywalking-apm-9.4.0.tar.gz -C /usr/local/
- 然后修改webapp下的application.yml文件:
vim /usr/local/apache-skywalking-apm-bin/webapp/application.yml
- 编辑skywalking的application.yml配置:
vim /usr/local/apache-skywalking-apm-bin/config/application.yml
- 启动SkyWalking
1)进入到SkyWalking的bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
2)启动SkyWalking:./startup.sh
2、SkyWalking自定义链路追踪
-
在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>
-
在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虚拟机上的。
-
打开Navicat,创建连接后,对连接名右键新建数据库test。
-
在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');
-
在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; }
-
在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注解。
-
在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); }
-
在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); } }
-
在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); } }
-
测试
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的调用日志
-
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>
-
在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>
-
在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}
-
测试
1)启动Eureka7001和Eureka7002以及cloud-provider-skywalking-payment8001服务
2)在浏览器上访问:http://localhost:8001/user/findByAll
3)此时浏览器访问:http://192.168.126.11:8068
,点击导航条的Log,即可出现这个调用的日志。
二、SkyWalking链路追踪的告警功能
1、SkyWalking的告警规则
-
Skywalking默认支持7种通知:
web、grpc、微信、钉钉、飞书、华为weLink、slack -
默认规则
Skywalking默认提供的 alarm-settings.yml ,定义的告警规则如下:
1)过去3分钟内服务平均响应时间超过1秒
2)服务成功率在过去2分钟内低于80%
3)服务90%响应时间在过去3分钟内高于1000毫秒
4)服务实例在过去2分钟内的平均响应时间超过1秒
5)端点平均响应时间过去2分钟超过1秒 -
告警规则
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} 会解析成规则名称 -
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自定义告警规则
-
编辑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
-
重启SkyWalking
1)将SkyWalking服务杀死
2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
3)启动SkyWalking服务:./startup.sh
-
修改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的告警规则。
-
此时UserController也需要进行异常的抛出。
-
测试
1)启动Eureka7001和Eureka7002以及重启cloud-provider-skywalking-payment8001服务
2)在浏览器上访问:http://localhost:8001/user/findByAll
3)此时浏览器访问:http://192.168.126.11:8068
,点击左边导航条的告警标志,即可出现这个告警信息。如果没有告警信息,可以多请求几次或者延长休眠时间。
3、SkyWalking实现网络钩子Webhooks
-
在父工程cloud下,右键new Module,创建子模块项目cloud-alarm9090
-
在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>
-
将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 启动 *****"); } }
-
在cloud-alarm9090项目的resources目录下创建application.yml文件,配置如下
server: port: 9090
-
在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; } }
-
在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("\nscopeId:").append(info.getScopeId()) .append("\nScope实体:").append(info.getScope()) .append("\n告警消息:").append(info.getAlarmMessage()) .append("\n告警规则:").append(info.getRuleName()) .append("\n\n------------------------\n\n"); }); System.out.println(builder); } }
-
先从网络适配器的VMnet8中获取到虚拟机在同一个网关下的ip地址,用来配置到下面的告警规则文件alarm-settings.yml中
-
编辑alarm-settings.yml告警规则文件:
vim /usr/local/apache-skywalking-apm-bin/config/alarm-settings.yml
,添加如下配置webhooks: # 钉钉告警 - http://192.168.126.1:9090/alarm/dingding
即将告警消息使用Post请求推送到这个地址中。
-
重启SkyWalking
1)将SkyWalking服务杀死
2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
3)启动SkyWalking服务:./startup.sh
-
关闭防火墙
-
测试
1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及AlarmMain9090服务
2)在浏览器上访问:http://localhost:8001/user/findByAll
3)AlarmMain9090服务的控制台会打印如下信息
如果没有出现,则多访问几次http://localhost:8001/user/findByAll
4、SkyWalking使用网络钩子Webhooks实现钉钉告警
- 创建钉钉群聊,然后在群里的右上角点击设置,选择机器人,再选择添加机器人,再次选择添加机器人,选择自定义(通过Webhook接入自定义服务),再点击添加,按下图进行配置,然后把秘钥复制起来,点击完成即可。最后将网络钩子Webhook的链接和秘钥复制下来放在cloud-alarm9090项目的yml文件中进行配置即可。
-
在cloud-alarm9090项目的POM文件中添加如下依赖
<!--钉钉工具包--> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibaba-dingtalk-service-sdk</artifactId> <version>2.0.0</version> </dependency>
-
修改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 + "\n" + 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 = "×tamp=" + 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("业务告警:\n" + 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方法,将原本从控制台打印,变成推送消息到第三方钉钉的群聊中。
-
修改cloud-alarm9090项目的application.yml,配置如下
server: port: 9090 dingding: # 钉钉网络钩子的地址 webhook: https://oapi.dingtalk.com/robot/send?access_token=2d5c8bdec15d56f9548bee2713562b57c4d5f1ca35eb45eb45fdcb8ffaae7719 # 秘钥 secret: SEC6b75579d66b1fe5e5a73cc2186db61e6499e13e493fe755f6c78219e4ed1eade
-
关闭防火墙
-
测试
1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及重启AlarmMain9090服务
2)在浏览器上访问:http://localhost:8001/user/findByAll
3)钉钉中的群聊机器人就会发送告警信息。
5、SkyWalking使用网络钩子Webhooks实现邮件告警
-
登录到qq邮箱后,点击设置,再点击账户,往下拉到第二个图的管理服务那里,一点击到第三个图那里,点击生成授权码,手机验证后就会出现授权码。复制该授权码,待会需要配置。
-
在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>
-
在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,端口号465或587 # 默认的邮件编码为UTF-8 default-encoding: UTF-8 properties: mail: smtp: #需要验证用户名密码 auth: true starttls: # 设置为配置SMTP连接的属性。要使用STARTTLS,必须设置以下属性 enable: true required: true
-
在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); }); }
-
编辑alarm-settings.yml告警规则文件:
vim /usr/local/apache-skywalking-apm-bin/config/alarm-settings.yml
,添加如下配置webhooks: # 邮件告警 - http://192.168.126.1:9090/alarm/sendMail
-
重启SkyWalking
1)将SkyWalking服务杀死
2)进入到bin目录下:cd /usr/local/apache-skywalking-apm-bin/bin
3)启动SkyWalking服务:./startup.sh
-
测试
1)启动Eureka7001和Eureka7002和cloud-provider-skywalking-payment8001以及重启AlarmMain9090服务
2)在浏览器上访问:http://localhost:8001/user/findByAll
3)qq邮箱就会发送消息到指定邮箱
三、全方位监控告警系统
1、系统监控报警框架Prometheus以及UI可视化Grafana的概论
-
Prometheus的具体流程:
1)Prometheus Server: 用于定时抓取数据指标(metrics)、存储时间序列数据(TSDB)
2)Jobs/exporte: 收集被监控端数据并暴露指标给Prometheus
3)Pushgateway :监控端的数据会用push的方式主动传给此组件,随后被Prometheus 服务定时pull此组件数据即可
4)Alertmanager :报警组件,可以通过邮箱、微信等方式
5)Web UI :用于多样的UI展示,一般为Grafana
6)还有一些例如配置自动发现目标的小组件和后端存储组件 -
Prometheus的特点
- 多维度数据模型。
- 灵活的查询语言。
- 不依赖分布式存储,单个服务器节点是自主的。
- 通过基于HTTP的pull方式采集时序数据。
- 可以通过中间网关进行时序数据推送。
- 通过服务发现或者静态配置来发现目标服务对象。
- 支持多种多样的图表和界面展示,比如Grafana等。
-
Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示。Grafana提供了对prometheus的友好支持,各种工具帮助你构建更加炫酷的数据可视化。
-
Grafana特点
- 可视化:快速和灵活的客户端图形具有多种选项。面板插件为许多不同的方式可视化指标和日志。
- 报警:可视化地为最重要的指标定义警报规则。Grafana将持续评估它们,并发送通知。
- 通知:警报更改状态时,它会发出通知。接收电子邮件通知。
- 动态仪表盘:使用模板变量创建动态和可重用的仪表板,这些模板变量作为下拉菜单出现在仪表板顶部。
- 混合数据源:在同一个图中混合不同的数据源!可以根据每个查询指定数据源。这甚至适用于自定义数据源。
- 注释:注释来自不同数据源图表。将鼠标悬停在事件上可以显示完整的事件元数据和标记。
- 过滤器:过滤器允许您动态创建新的键/值过滤器,这些过滤器将自动应用于使用该数据源的所有查询。
2、Prometheus服务的环境搭建
- 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
- 将prometheus上传到虚拟机的/opt目录下,在opt目录中进行解压缩到到/usr/local目录中:
tar -zxvf prometheus-2.44.0-rc.2.linux-amd64.tar.gz -C /usr/local
- 进入到prometheus的安装目录:
cd /usr/local/prometheus-2.44.0-rc.2.linux-amd64/
- 启动prometheus服务并指定它的配置文件:
./prometheus --config.file=prometheus.yml
默认指定的配置文件就是prometheus.yml;所以此时可以不用指定。- 如果此时端口号被占用,先检查9090是哪个进程在占用:
lsof -i :9090
因为prometheus默认端口就是9090 - 杀死该进程:
kill -9 PID号
,再启动就可以了
- 如果此时端口号被占用,先检查9090是哪个进程在占用:
- 在浏览器上访问:
http://192.168.126.11:9090
- 如果后面需要关闭prometheus服务
- 先找到prometheus服务的PID号:
pgrep -f prometheus
- 杀死该进程:
kill -9 PID号
- 先找到prometheus服务的PID号:
3、Grafana服务的环境搭建
- 因为前面打开了Prometheus服务,直接再打开一个窗口,双击该虚拟机的Session的名字即可打开新窗口。
- 拉取Grafana的最新镜像:
docker pull grafana/grafana-enterprise
- 创建并运行容器:
docker run -d --name=grafana -p 3000:3000 grafana/grafana-enterprise
- 在浏览器中访问:
http://192.168.126.11:3000
Grafana的帐号和密码都是admin - 登陆进去后,按下图步骤点击Data sources,然后点击Add data source,即配置数据源。
- 再点击Prometheus,即配置Prometheus的数据源,配置如下,然后拉到下面,点击save保存即可
即配置prometheus的服务地址,以及自定义该配置的名字。 - 按下图配置Grafana模板,12856是Grafana模板ID。更多模板请参考:
https://grafana.com/grafana/dashboards
- 按下图选择刚刚的配置名,然后点击import即可
- 然后就会出现下图的DashBoard,即仪表盘
4、将微服务应用接入Prometheus服务
-
在cloud父工程下,创建一个子模块项目cloud-provider-prometheus-payment8001
-
在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>
-
在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 服务。
-
将cloud-provider-payment8001项目的com.zzx.controller包以及它的主启动类PaymentMain8001复制到cloud-provider-prometheus-payment8001项目中
-
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); } }
-
修改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
-
浏览器访问:
http://192.168.126.11:9090
,然后点击Status,选择到targets。
如果cloud-provider-prometheus-payment8001的状态显示up,证明暴露指标成功 -
浏览器访问:
http://192.168.126.11:3000/dashboards
,然后选择刚刚的界面,能出现下图即可。
总结
- SkyWalking官方推荐使用Elasticsearch数据库。
1)SkyWalking连接Elasticsearch数据库,需要在SkyWalking安装目录的config/application.yml文件中的storage属性中进行配置。skywalking9.4.0有个坑,就是你在启动SkyWalking后,再去切换数据库,再次启动时,会出现不显示数据的问题。需要重新安装,然后在配置完成后,再去启动SkyWalking服务即可。
2)SkyWalking自定义链路追踪,需要在追踪的方法上加上@Trace注解。然后SkyWalking服务就会对该方法从开始到结束的所有操作进行追踪。 - 1)SkyWalking的调用日志,需要在POM文件中,引入收集日志的依赖;然后需要在resources下创建一个logback.xml配置文件;最后在JavaAgent中配置SkyWalking服务主机的ip和端口号等信息;这样就可以将SkyWalking收集到的日志信息上传到SkyWalking中。
2)Skywalking发送告警的基本原理是每隔一段时间轮询Skywalking-collector收集到的链路追踪的数据。Skywalking告警可以支持第三方应用,即将告警信息推送到第三方应用。
3)SkyWalking自定义告警信息,需要在SkyWalking的安装目录下的config目录的alarm-settings.yml告警规则文件中进行添加自定义告警规则。然后重启SkyWalking服务即可。 - 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告警规则文件中进行添加回调方法的请求路径,在对应方法中实现这个邮箱告警即可。 - 1)Prometheus 是一套开源的系统监控报警框架。全方位的监控告警系统主要作用是监控微服务运行状况。Grafana提供了对prometheus的友好支持,各种工具帮助你构建更加炫酷的数据可视化。
2)微服务应用接入Prometheus服务,再由Grafana服务进行页面展示。先手需要Grafana服务中配置Prometheus服务;然后引入micrometer-registry-prometheus等依赖;然后在application.yml配置文件中开启Actuator服务以及指定它的应用名给Grafana等;在主启动类中实现暴露指标到prometheus服务的方法;在虚拟机中修改prometheus安装目录的prometheus.yml配置文件,设置获取应用指标的配置即可。