無論是使用SpringBootAdmin還是使用Prometheus+Grafana都離不開SpringBoot提供的核心元件Actuator。提到Actuator,又不得不提Micrometer,從SpringBoot2.x開始,Actuator的功能實現都是基於Micrometer的。
Micrometer通過儀表使用者端為各種健康監控系統提供了一個簡單的外觀Facade(Facade模式是23種設計模式中的一種,也叫外觀模式 / 門面模式,Facade(外觀)模式為子系統中的各類(或結構與方法)提供一個簡明一致的介面,隱藏子系統的複雜性,使子系統更加容易使用。它是為子系統中的一組介面所提供的一個一致的介面。)。類似於SLF4J,我們可以自由選擇log4j2、logback等紀錄檔框架一樣,Micrometer支援靈活切換或者多種並存的健康監控系統檢測基於 JVM 的應用程式。
Micrometer提供的功能:
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: 是一款開源的系統和服務監控系統,屬於雲原生計算基金會專案。它可以通過設定的時間間隔從設定的目標系統採集指標資料,儲存指標資料(時序資料庫),評估規則表示式,顯示結果,並在檢測到指定條件時觸發警報。
雖然Prometheus也支援視覺化介面展示,但是介面不美觀,更多人選擇使用Grafana來展示Prometheus的監控資料。
Grafana:Grafana是一款開源的資料視覺化工具。它提供對資料指標的查詢、視覺化和告警,它可以實現無論資料儲存在哪裡,都可以與您的團隊建立、探索和共用十分美觀的儀表盤資料視覺化,並培養資料驅動的文化。
我們使用Docker來安裝需要的Prometheus+Grafana,通常情況下,我們會根據業務需求來安裝需要的元件,在這裡健康監控系統也是這樣,如果我們的微服務部署在Docker容器中,那麼我們需要安裝cAdvisor元件來監控Docker相關資料指標,如果要採集系統環境資料,那麼需要安裝 Node Exporter 元件,而且告警元件也是和Prometheus分開的,如果需要告警功能,同樣需要安裝Alertmanager元件,這一連串元件的組合,自然讓我們想到使用docker-compose來安裝我們需要所有元件。
參考 https://github.com/stefanprodan/dockprom 我們編寫兩個docker-compose檔案:
# 建立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
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 "https://gcr.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers),請自行設定將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
同在伺服器端執行一樣,這裡執行會報錯,請自行切換可以存取到的映象倉庫。
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
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
請注意,在選擇micrometer-registry-prometheus版本時,一定要和框架中SpringBoot引入的micrometer相匹配的版本,否則不相容。
......
<!-- prometheus 微服務監控 和 spring-boot-admin二選一-->
<micrometer.registry.prometheus.version>1.5.14</micrometer.registry.prometheus.version>
......
<!-- actuator prometheus 健康檢查https://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>
......
<!-- 如果使用prometheus進行健康檢查,這裡統一引入依賴。如果使用SpringBootAdmin,這裡註釋掉。-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
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
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']
通過以上步驟已經能夠搭建和設定簡單的Actuator(Micrometer)+ Prometheus + Grafana 微服務健康監控系統,檢視Prometheus / Grafana 官方檔案,我們可以知道其提供的功能非常豐富,在實際使用過程中,我們需要根據自己的業務需求進行更細維度的部署和設定。
服務健康監控系統是保障我們系統服務正常執行的必要工具,設定部署非常方便,但是,我們生產環境一定要注意系統安全問題,不要把健康檢查的端點暴露出去,該做鑑權的做鑑權,該做安全防護的做安全防護,不要因為方便健康監控而增加安全風險。
Gitee: https://gitee.com/wmz1930/GitEgg
GitHub: https://github.com/wmz1930/GitEgg