身处小公司,全栈(全干)攻城狮,没有闲篇,直接开干。
一、准备内容
本次搭建环境共涉及2台服务器,分别是A服务器(192.168.1.30),B服务器(192.168.1.31)
8899: cAdvisor--docker容器监控
9090: prometheus端口
9100:node_exporter---收集主机的监控数据
9093: alertmanager ---告警组件
9094:飞书端口
需要防火墙放开端口,就不一一列举。
命令如下:
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" port protocol="tcp" port="9093" accept"
firewall-cmd --reload
如果部署在阿里云等云服务器,还需要在阿里云的安全规则中放行相关端口。
1.2需要在各个服务的pom中添加依赖
<!-- 监控相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
1.3需要在各个服务的nacos配置中添加如下内容
另外需要注意:配置以后可能不生效,需要重启nacos和相关服务
management:
endpoints:
web:
exposure:
# 暴露相关项目信息
include: "prometheus" # 只暴露/actuator/prometheus
endpoint:
prometheus:
enabled: true
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
1.4 在Dockerfile中java执行命令添加参数
此参数可不加,根据自己情况而定。
"-XX:+HeapDumpOnOutOfMemoryError","-XX:HeapDumpPath=/data/soft/dump/服务.hprof","-XX:+ExitOnOutOfMemoryError","-XX:MaxRAMPercentage=75.0"
其中:
-XX:+HeapDumpOnOutOfMemoryError:参数表示当JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=/temp/dump/服务.hprof:生成dump目录文件的位置以及文件名称
-XX:+ExitOnOutOfMemoryError:JVM在第一次出现内存不足错误时退出,启动JVM实例
-XX:MaxRAMPercentage=75.0: 这为JVM定义了75%的总内存限制
1.5 安装Telnet服务
yum install telnet telnet-server
二、架构图
架构设计图如下所示:
三、安装相关软件
3.1安装Node_Exporter
事实上,对于Prometheus服务而言,其是负责收集、存储、查看监控数据。而真正直接进行监控则是通过Exporter完成的。可以看到,Exporter相当于是Prometheus服务的客户端,负责向其提供监控数据。具体地,针对不同的被监控目标,我们需要使用不同的Exporter。这里,我们期望能够监控本机的运行状态(CPU、内存、磁盘等参数)。故这里我们需要下载一个Node Exporter用来采集主机的监控数据。由于这里我们需要监控的是主机,所以一般不推荐使用Docker来部署Node Exporter。需要在A、B服务器都安装。
# 下载 node exporter
wget --no-check-certificate https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz
# 解压
tar xvfz node_exporter-1.3.1.linux-amd64.tar.gz
# 启动 Node Exporter
cd node_exporter-1.3.1.linux-amd64
./node_exporter &
至此我们的Node Exporter就已经启动成功了,且运行在9100端口
故通过 http://192.168.1.30:9100/metrics 即可直接访问看到其采集的监控数据,如果访问不了,可能需要开启防火墙端口。
3.2 安装容器监控cAdvisor
现如今Docker部署已经愈来愈流行,为了更好监控Dcoker整体的运行情况。Google开源的一款用于分析、展示容器运行状态的可视化工具——cAdvisor。需要在A、B服务器都安装。
# 拉取镜像
docker pull google/cadvisor
# 启动容器
docker run -idt --name=mycAdvisor \
-p 8899:8080 -d \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
-v /dev/disk/:/dev/disk:ro \
--privileged \
--device=/dev/kmsg \
-m 300m \
google/cadvisor
具体地,我们可通过 http://192.168.1.30:8899来访问其监控页面,查看Dcoker中整体及各容器的监控指标。值得一提的是,cAdvisor原生支持Prometheu,通过 http://192.168.1.30:8899/metrics 即可看到其采集的监控数据。
此服务安装到A服务器。
下载镜像:
docker pull prom/alertmanager
配置参数:/data/soft/alertmanager/alertmanager.yml
# 相关路由规则
route:
group_by: [...] # 分组, ... 表示不分组
group_wait: 60s # 同一组 告警 需要等待多少s才能发出
group_interval: 5m # 同一组的多批次告警间隔多少秒后,才能发出
repeat_interval: 1h # 重复告警要等待多久后才能再次发出去,目的是为了避免重复的消息发送多次
receiver: 'web.hook' # receiver名称,对应 receivers.name
# 配置报警方式
receivers:
- name: 'web.hook'
webhook_configs:
# 通知url
- url: 'http://192.168.1.30:9094/alert/card'
启动:
需要先链接
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
docker run -d --name alertmanager \
-p 9093:9093 \
-m 200m \
-v /etc/localtime:/etc/localtime \
-v /data/soft/alertmanager:/data \
-v /data/soft/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
prom/alertmanager
3.4飞书群聊配置
主要是获取飞书token
1.创建一个飞书群聊,在 设置 中选择群机器人 --> 选择 添加机器人。
2.选择自定义机器人------需要在pc端才能添加,手机端看不到"自定义机器人"这个选项
3.选择添加后,url后面就是 飞书的oken,在prometheus的配置中需要用到。
https://open.feishu.cn/open-apis/bot/v2/hook/7xxxxxxxx6aa5ad
4.在安全设置中勾选 自定义关键词,在发送的消息中存在 配置的关键词才能够正常发送。
3.5安装飞书镜像
token获取参考:3.4
注意:直接把token放到启动参数中,不用在xml配置
docker run -d --name prom-alert-feishu --restart=always \
-p 9094:8080 \
-e FEISHU_TOKEN=从3.4步骤中获取的飞书token \
-m 300m \
javafamily/prometheus-webhook-feishu:2.3.2-SNAPSHOT
3.6 配置Prometheus的rule规则
创建目录/data/soft/prometheus/rules/
并创建如下文件:
default_rule_A.xml,disk_rule_A.xml,memory_rule_A.xml
default_rule_B.xml,disk_rule_B.xml,memory_rule_B.xml
其中:
default_rule_A.xml内容如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 实例存活报警
rules:
- alert: 实例存活报警
expr: up{serviceId="test_server_1"} == 0 #注意此处的服务名
for: 30s
labels:
severity: emergency
annotations:
title: "服务宕机报警"
serviceName: "{{ $labels.serviceName }}"
instance: "{{ $labels.instance }}"
btn: "点击查看详情 :玫瑰:"
template: '服务 **${serviceName}**(${instance}) 断联, 请及时处理!'
description: '服务宕机'
default_rule_B.xml 如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 实例存活报警
rules:
- alert: 实例存活报警
expr: up{serviceId="test_server_2"} == 0 #注意此处的服务名
for: 30s
labels:
severity: emergency
annotations:
title: "服务宕机报警"
serviceName: "{{ $labels.serviceName }}"
instance: "{{ $labels.instance }}"
btn: "点击查看详情 :玫瑰:"
template: '服务 **${serviceName}**(${instance}) 断联, 请及时处理!'
description: '服务宕机'
disk_rule_A.xml配置如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 磁盘预警
rules:
- alert: 磁盘使用率预警
expr: (node_filesystem_size_bytes{job="测试环境-30",device="/dev/vda1"}-node_filesystem_avail_bytes{job="测试环境-30",device="/dev/vda1"})/node_filesystem_size_bytes{job="测试环境-30",device="/dev/vda1"} * 100 > 90
for: 30s
labels:
severity: emergency
annotations:
title: "磁盘使用率预警"
serviceName: "{{ $labels.job }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: "**${serviceName}**(${instance}) 服务器磁盘设备使用率超过 **90%**, 请及时处理!\r\n当前值: ${value}%!"
btn: "点击查看详情 :玫瑰:"
disk_rule_B.xml配置如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 磁盘预警
rules:
- alert: 磁盘使用率预警
expr: (node_filesystem_size_bytes{job="测试环境-31",device="/dev/vda1"}-node_filesystem_avail_bytes{job="测试环境-31",device="/dev/vda1"})/node_filesystem_size_bytes{job="测试环境-31",device="/dev/vda1"} * 100 > 90
for: 30s
labels:
severity: emergency
annotations:
title: "磁盘使用率预警"
serviceName: "{{ $labels.job }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: "**${serviceName}**(${instance}) 服务器磁盘设备使用率超过 **90%**, 请及时处理!\r\n当前值: ${value}%!"
btn: "点击查看详情 :玫瑰:"
memory_rule_A.xml配置如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 内存预警
rules:
- alert: 内存使用率预警
expr: (node_memory_MemTotal_bytes{job="测试环境-30"} - (node_memory_MemFree_bytes{job="测试环境-30"}+node_memory_Buffers_bytes{job="测试环境-30"}+node_memory_Cached_bytes{job="测试环境-30"} )) / node_memory_MemTotal_bytes{job="测试环境-30"} * 100 >90
for: 30s
labels:
severity: emergency
annotations:
title: "内存使用率预警"
serviceName: "{{ $labels.name }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: '测试环境-30服务器 内存使用率已经超过阈值 **90%**, 请及时处理!\r\n当前值: ${value}%'
btn: "点击查看详情 :玫瑰:"
- alert: 内存使用率预警
expr: (container_memory_usage_bytes{job="测试环境cAdvisor-30",image="test-server"}-container_memory_cache{job="测试环境cAdvisor-30",image="test-server"})/container_spec_memory_limit_bytes{job="测试环境cAdvisor-30",image="test-server"} * 100 >90
for: 30s
labels:
severity: emergency
annotations:
title: "内存使用率预警"
serviceName: "{{ $labels.name }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: '**${serviceName}**(${instance}) 内存使用率已经超过阈值 **90%**, 请及时处理!\r\n当前值: ${value}%'
btn: "点击查看详情 :玫瑰:"
memory_rule_B.xml配置如下:
# 每个group可以定义多个告警规则(rule)
groups:
- name: 内存预警
rules:
- alert: 内存使用率预警
expr: (node_memory_MemTotal_bytes{job="测试环境-31"} - (node_memory_MemFree_bytes{job="测试环境-31"}+node_memory_Buffers_bytes{job="测试环境-31"}+node_memory_Cached_bytes{job="测试环境-31"} )) / node_memory_MemTotal_bytes{job="测试环境-31"} * 100 >90
for: 31s
labels:
severity: emergency
annotations:
title: "内存使用率预警"
serviceName: "{{ $labels.name }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: '测试环境-31服务器 内存使用率已经超过阈值 **90%**, 请及时处理!\r\n当前值: ${value}%'
btn: "点击查看详情 :玫瑰:"
- alert: 内存使用率预警
expr: (container_memory_usage_bytes{job="测试环境cAdvisor-31",image="test-server"}-container_memory_cache{job="测试环境cAdvisor-31",image="test-server"})/container_spec_memory_limit_bytes{job="测试环境cAdvisor-31",image="test-server"} * 100 >90
for: 31s
labels:
severity: emergency
annotations:
title: "内存使用率预警"
serviceName: "{{ $labels.name }}"
instance: "{{ $labels.instance }}"
value: "{{ $value }}"
template: '**${serviceName}**(${instance}) 内存使用率已经超过阈值 **90%**, 请及时处理!\r\n当前值: ${value}%'
btn: "点击查看详情 :玫瑰:"
3.7 安装Prometheus
# 拉取镜像
docker pull prom/prometheus
在/data/soft/prometheus路径下创建文件prometheus.yml,
内容如下:
global:
scrape_interval: 30s # 全局抓取数据时间,默认 60s,可在job中覆盖
evaluation_interval: 30s # 全局告警计算周期,默认 60s,可在job中覆盖
# alert Manager配置
alerting:
alertmanagers:
- static_configs:
- targets:
- 192.168.1.30:9093
# rule规则配置
rule_files:
- 'rules/*.yml'
scrape_configs:
# prometheus自带默认 job,不可删除
- job_name: 'prometheus'
metrics_path: '/metrics'
static_configs:
- targets: ['192.168.1.30:9090'] # 抓取数据url,确保在容器中能够访问到,使用docker启动不能写localhost
- job_name: '测试环境-30'
static_configs:
- targets: ['192.168.1.30:9100']
# 收集Docker容器的监控数据
- job_name: '测试环境cAdvisor-30'
static_configs:
- targets: ['192.168.1.30:8899']
- job_name: '测试环境-31'
static_configs:
- targets: ['192.168.1.31:9100']
# 收集Docker容器的监控数据
- job_name: '测试环境cAdvisor-31'
static_configs:
- targets: ['192.168.1.31:8899']
# 服务实例 job,可配置多个
- job_name: '测试-test-监控-30'
scrape_interval: 15s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.1.30:27000']
labels:
serviceId: 'test_server_1' #注意此处名称
serviceName: '测试-test-监控(30服务器)'
- job_name: '测试-test-监控-31'
scrape_interval: 15s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.1.31:27000']
labels:
serviceId: 'test_server_2' #注意此处名称
serviceName: '测试-test-监控(31服务器)'
启动prometheus
# 启动容器
docker run -idt \
--name prometheus \
-p 9090:9090 \
-m 1024m \
-v /etc/localtime:/etc/localtime \
-v /data/soft/prometheus:/data \
prom/prometheus --config.file=/data/prometheus.yml
现在访问其Web管理页面( http://192.168.1.30:9090 ),即可看到Prometheus服务被正确启动了。
至此,已经配置完成。
效果如下图所示:
参考文章:
https://blog.csdn.net/wu6cfp38/article/details/129405279