SpringCloud微服務實戰——搭建企業級開發框架(四十五):【微服務監控告警實現方式二】使用Actuator(Micrometer)+Prometheus+Grafana實現完整的微服務監控
- 2022 年 7 月 29 日
- 筆記
- Oauth2, SpringCloud, SpringSecurity, 微服務
無論是使用SpringBootAdmin還是使用Prometheus+Grafana都離不開SpringBoot提供的核心組件Actuator。提到Actuator,又不得不提Micrometer,從SpringBoot2.x開始,Actuator的功能實現都是基於Micrometer的。
Micrometer通過儀錶客戶端為各種健康監控系統提供了一個簡單的外觀Facade(Facade模式是23種設計模式中的一種,也叫外觀模式 / 門面模式,Facade(外觀)模式為子系統中的各類(或結構與方法)提供一個簡明一致的介面,隱藏子系統的複雜性,使子系統更加容易使用。它是為子系統中的一組介面所提供的一個一致的介面。)。類似於SLF4J,我們可以自由選擇log4j2、logback等日誌框架一樣,Micrometer支援靈活切換或者多種並存的健康監控系統檢測基於 JVM 的應用程式。
Micrometer提供的功能:
- 尺寸指標(Dimensional Metrics):Micrometer 為計時器、儀錶、計數器、分布摘要和長任務計時器提供了與供應商無關的介面,具有維度數據模型,當與維度監控系統配對時,允許有效訪問特定命名的度量,並具有向下鑽取的能力跨越其維度。
- 預配置綁定(Pre-configured Bindings):開箱即用的快取、類載入器、垃圾收集、處理器利用率、執行緒池等工具,更適合可操作的洞察力。
- Spring集成(Integrated into Spring):Micrometer 是一個檢測庫,支援從 Spring Boot 應用程式交付應用程式指標。
Micrometer支援的監控系統:
AppOptics, Azure Monitor, Netflix Atlas, CloudWatch, Datadog, Dynatrace, Elastic, Ganglia, Graphite, Humio, Influx/Telegraf, JMX, KairosDB, New Relic, Prometheus, SignalFx, Google Stackdriver, StatsD, and Wavefront.
上文中我們說明了如何搭建Spring Boot Admin的微服務健康檢查監控系統,簡單的應用使用Spring Boot Admin即可,複雜的集群應用建議使用Micrometer 支援的多種靈活可配的監控系統,這裡我們選擇目前使用比較廣泛的Prometheus+Grafana監控系統。
兩種方式都能夠實現微服務的健康檢查統計展示和告警,Prometheus+Grafana在功能和介面美觀上更強大一些,並且可以查看歷史數據,而SpringBootAdmin優點是部署十分簡單,不需要部署太多的環境軟體,本身就是一個微服務。在兩種方式的選擇上,如果是小的項目,比如單體應用,雙擊熱備,前期可以先使用SpringBootAdmin,隨著業務的發展,可以考慮使用Prometheus+Grafana。
一、Prometheus+Grafana相關介紹
1、Prometheus介紹
Prometheus: 是一款開源的系統和服務監控系統,屬於雲原生計算基金會項目。它可以通過設置的時間間隔從配置的目標系統採集指標數據,保存指標數據(時序資料庫),評估規則表達式,顯示結果,並在檢測到指定條件時觸發警報。
- 多維數據模型:Prometheus 實現了一個高維數據模型,它從根本上將所有數據存儲為時間序列:屬於同一指標和同一組標記維度的時間戳值。 除了存儲的時間序列,Prometheus 可能會生成臨時派生的時間序列作為查詢的結果。
- 高效存儲:Prometheus 以高效的自定義格式將時間序列存儲在記憶體和本地磁碟上(內置TSDB資料庫,同時也提供了遠程存儲介面),擴展是通過功能分片和聯合來實現的。
- PromQL:一種強大且靈活的查詢語言,PromQL 允許對收集的時間序列數據進行切片和切塊,以生成臨時圖形、表格和警報。
- 不依賴分散式存儲,操作簡單:每台伺服器的可靠性都是獨立的,僅依賴於本地存儲。用 Go 編寫,所有二進位文件都是靜態鏈接的,易於部署。
- HTTP拉取模型: 通過抓取HTTP端點採集時序數據。
- 通過用於批處理作業的中間網關支援推送時間序列數據。
- 通過服務發現或靜態配置發現目標。
- 出色的可視化:Prometheus 有多種數據可視化模式,內置表達式瀏覽器、Grafana 集成和控制台模板語言。
- 支援分層和水平聯合。
2、Grafana介紹
雖然Prometheus也支援可視化介面展示,但是介面不美觀,更多人選擇使用Grafana來展示Prometheus的監控數據。
Grafana:Grafana是一款開源的數據可視化工具。它提供對數據指標的查詢、可視化和告警,它可以實現無論數據存儲在哪裡,都可以與您的團隊創建、探索和共享十分美觀的儀錶盤數據可視化,並培養數據驅動的文化。
- 可視化:具有多種選項的快速靈活的客戶端圖表。面板插件提供了許多不同的方式來可視化指標和日誌。
- 動態儀錶板:使用在儀錶板頂部顯示為下拉列表的模板變數創建動態和可重複使用的儀錶板。
- 探索指標:通過即席查詢(是用戶根據自己的需求,靈活的選擇查詢條件,系統能夠根據用戶的選擇生成相應的統計報表)和動態鑽取探索您的數據。拆分視圖並並排比較不同的時間範圍、查詢和數據源。
- 探索日誌:體驗從指標切換到帶有保留標籤過濾器的日誌的魔力。快速搜索所有日誌或實時流式傳輸它們。
- 告警:為您最重要的指標直觀地定義告警規則。Grafana 將持續評估並向 Slack、PagerDuty、VictorOps、OpsGenie 等系統發送通知。
- 混合數據源:在同一個圖中混合不同的數據源!您可以基於每個查詢指定數據源。這甚至適用於自定義數據源。
二、使用Docker安裝配置Prometheus+Grafana
我們使用Docker來安裝需要的Prometheus+Grafana,通常情況下,我們會根據業務需求來安裝需要的組件,在這裡健康監控系統也是這樣,如果我們的微服務部署在Docker容器中,那麼我們需要安裝cAdvisor組件來監控Docker相關數據指標,如果要採集系統環境數據,那麼需要安裝 Node Exporter 組件,而且告警組件也是和Prometheus分開的,如果需要告警功能,同樣需要安裝Alertmanager組件,這一連串組件的組合,自然讓我們想到使用docker-compose來安裝我們需要所有組件。
參考 //github.com/stefanprodan/dockprom 我們編寫兩個docker-compose文件:
- 服務端:數據採集、展示、告警,安裝 prometheus、grafana、cadvisor、alertmanager、node-exporter、caddy
- 客戶端: 只需安裝 cadvisor、node-exporter用於採集本機數據。
1、準備Docker宿主主機的安裝部署目錄。
# 創建prometheus掛在目錄
mkdir /data/monitor/prometheus
cd /data/monitor/prometheus
touch prometheus.yml
mkdir /data/monitor/prometheus_data
# 創建alertmanager掛在目錄
mkdir -p /data/monitor/alertmanager
# 創建grafana掛在目錄
mkdir -p /data/monitor/grafana_data
mkdir -p /data/monitor/grafana/provisioning/dashboards
mkdir -p /data/monitor/grafana/provisioning/datasources
2、編寫docker-compose-prometheus-server.yml,此處為服務編排模板參考,因某些原因docker鏡像倉庫無法訪問,需切換到能夠訪問到的鏡像倉庫。
- docker-compose-prometheus-server.yml
version: '3.2'
networks:
monitor-net:
driver: bridge
volumes:
prometheus_data: {}
grafana_data: {}
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- /data/monitor/prometheus:/etc/prometheus
- /data/monitor/prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
restart: unless-stopped
expose:
- 9090
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
volumes:
- /data/monitor/alertmanager:/etc/alertmanager
command:
- '--config.file=/etc/alertmanager/config.yml'
- '--storage.path=/alertmanager'
restart: unless-stopped
expose:
- 9093
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
nodeexporter:
image: prom/node-exporter:latest
container_name: nodeexporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
restart: unless-stopped
expose:
- 9100
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
privileged: true
devices:
- /dev/kmsg:/dev/kmsg
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
#- /cgroup:/cgroup:ro #doesn't work on MacOS only for Linux
restart: unless-stopped
expose:
- 8080
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
grafana:
image: grafana/grafana:latest
container_name: grafana
volumes:
- /data/monitor/grafana_data:/var/lib/grafana
- /data/monitor/grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards
- /data/monitor/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources
environment:
- GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
restart: unless-stopped
expose:
- 3000
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
pushgateway:
image: prom/pushgateway:latest
container_name: pushgateway
restart: unless-stopped
expose:
- 9091
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
caddy:
image: caddy:latest
container_name: caddy
ports:
- "3000:3000"
- "9090:9090"
- "9093:9093"
- "9091:9091"
volumes:
- ./caddy:/etc/caddy
environment:
- ADMIN_USER=${ADMIN_USER:-admin}
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin}
- ADMIN_PASSWORD_HASH=${ADMIN_PASSWORD_HASH:-JDJhJDE0JE91S1FrN0Z0VEsyWmhrQVpON1VzdHVLSDkyWHdsN0xNbEZYdnNIZm1pb2d1blg4Y09mL0ZP}
restart: unless-stopped
networks:
- monitor-net
labels:
org.label-schema.group: "monitoring"
在服務端安裝執行安裝命令:
docker-compose -f docker-compose-prometheus-server.yml up -d
執行會報錯,因無法訪問部分docker鏡像庫:Error response from daemon: Get “//gcr.io/v2/“: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers),請自行設置將docker切換到能夠訪問的雲伺服器。
3、編寫docker-compose-prometheus-client.yml,此處為服務編排模板參考,因某些原因docker鏡像倉庫無法訪問,需切換到能夠訪問到的鏡像倉庫。
version: '3.2'
services:
nodeexporter:
image: prom/node-exporter:latest
container_name: nodeexporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
restart: unless-stopped
network_mode: host
labels:
org.label-schema.group: "monitoring"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
privileged: true
devices:
- /dev/kmsg:/dev/kmsg
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /cgroup:/cgroup:ro
restart: unless-stopped
network_mode: host
labels:
org.label-schema.group: "monitoring"
在服務端安裝執行安裝命令:
docker-compose -f docker-compose-prometheus-server.yml up -d
同在服務端執行一樣,這裡執行會報錯,請自行切換可以訪問到的鏡像倉庫。
4、以上為生產環境所需的安裝方式配置參考,下面我們使用Docker進行最小安裝,來測試運行Prometheus+Grafana。
- 執行安裝Prometheus
docker run -d \
--restart=always \
-u root \
--name prometheus \
-p 9090:9090 \
-v /etc/localtime:/etc/localtime \
-v /data/monitor/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /data/monitor/prometheus_data:/prometheus \
prom/prometheus
- 執行安裝Grafana
docker run -d \
--restart=always \
-u root \
--name grafana \
-p 3000:3000 \
-v /data/grafana_data:/var/lib/grafana \
-v /data/grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards \
-v /data/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources \
-e GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin} \
-e GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} \
-e GF_USERS_ALLOW_SIGN_UP=false \
grafana/grafana
5、安裝成功後訪問鏈接查看是否成功
- Prometheus: //192.168.0.10:9090/
- Grafana://192.168.0.10:3000/ ,通過我們安裝時部署的用戶名密碼: admin / admin 登錄。
三、微服務相關配置及添加Prometheus支援
1、在gitegg-platform-bom工程中引入micrometer的prometheus依賴包。
請注意,在選擇micrometer-registry-prometheus版本時,一定要和框架中SpringBoot引入的micrometer相匹配的版本,否則不兼容。
......
<!-- prometheus 微服務監控 和 spring-boot-admin二選一-->
<micrometer.registry.prometheus.version>1.5.14</micrometer.registry.prometheus.version>
......
<!-- actuator prometheus 健康檢查//mvnrepository.com/artifact/io.micrometer/micrometer-registry-prometheus -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>${micrometer.registry.prometheus.version}</version>
</dependency>
......
2、gitegg-cloud工程的父pom.xml統一引入prometheus依賴包,這樣,我們就可以統一靈活切換使用的監控系統。
<!-- 如果使用prometheus進行健康檢查,這裡統一引入依賴。如果使用SpringBootAdmin,這裡注釋掉。-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
3、修改Nacos,開啟prometheus抓取端點。
metrics.tags.application: ${spring.application.name} 設置tag方便Prometheus抓取數據時區分不同的服務。
# 性能監控端點配置
management:
security:
enabled: true
role: ACTUATOR_ADMIN
endpoint:
health:
show-details: always
endpoints:
enabled-by-default: true
web:
base-path: /actuator
exposure:
include: '*'
metrics:
tags:
application: ${spring.application.name}
export:
prometheus:
enabled: true
server:
servlet:
context-path: /actuator
health:
mail:
enabled: false
4、查看啟動結果 //127.0.0.1:8002/actuator/prometheus
四、配置Prometheus+Grafana採集並展示微服務健康監控數據
1、編輯prometheus配置文件prometheus.yml,設置採集微服務端點
scrape_configs:
- job_name: 'actuator-gitegg'
basic_auth:
username: user
password: password
scrape_interval: 15s
scrape_timeout: 10s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['192.168.0.2:80','192.168.0.2:8002']
- basic_auth:設置採集端點的basic認證資訊
- metrics_path:設置prometheus採集端點的路徑
- static_configs.targets: 設置prometheus採集端點的地址
2、重啟prometheus,訪問介面status -> targets,查看採集端點狀態。
3、配置Grafana,添加prometheus數據源並展示JVM監控圖表。
- Configuration -> Data sources -> Add data source
- 添加Prometheus數據源地址 //192.168.0.10:9090/
- Import 儀錶盤,Grafana提供了很多內置的儀錶盤模板,官方模板地址://grafana.com/grafana/dashboards , 我們這裡選擇使用JVM (Micrometer)模板,輸入模板的地址//grafana.com/grafana/dashboards/4701或者模板的編號4701,然後點擊Load進行載入。
- 執行import後就可以看到我們導入的儀錶盤模板了,點擊右上角的Save進行保存。
通過以上步驟已經能夠搭建和配置簡單的Actuator(Micrometer)+ Prometheus + Grafana 微服務健康監控系統,查看Prometheus / Grafana 官方文檔,我們可以知道其提供的功能非常豐富,在實際使用過程中,我們需要根據自己的業務需求進行更細維度的部署和配置。
服務健康監控系統是保障我們系統服務正常運行的必要工具,配置部署非常方便,但是,我們生產環境一定要注意系統安全問題,不要把健康檢查的端點暴露出去,該做鑒權的做鑒權,該做安全防護的做安全防護,不要因為方便健康監控而增加安全風險。
源碼地址:
Gitee: //gitee.com/wmz1930/GitEgg
GitHub: //github.com/wmz1930/GitEgg