微服务可观测性:两套主流监控方案对比与Docker落地实操

微服务可观测性:两套主流监控方案对比与Docker落地实操

摘要:可观测性分为指标监控、链路追踪两大方向。本文对比两套生产常用方案,给出可直接复制的Docker Compose部署步骤,适合开发运维人员参考。 为了更形象的说明问题,我做了一个网页版本,点击这里查看 两套主流监控方案对比和部署实操

1 核心组件概念解释

为方便后续理解,直白介绍4个核心组件,全部结合实际工作场景。

1.1 Prometheus

Prometheus 是开源时序指标监控工具,用来采集、存储、查询各类数值型指标:服务器CPU、内存、接口QPS、错误率、数据库连接数等。 采用Pull拉取模型,定时主动抓取目标暴露的/metrics接口;自带PromQL查询语言,支持告警规则,是云原生环境指标监控的事实标准。

1.2 Grafana

Grafana 是开源可视化面板工具。本身不采集、不存储数据,只对接各类数据源(Prometheus、MySQL、Elasticsearch等),把数据渲染成折线图、大盘、报表。 社区有大量现成Dashboard模板,自定义能力强,我们日常看到的监控大盘基本都是Grafana实现。

1.3 SkyWalking

SkyWalking 是国产开源分布式链路追踪APM工具,面向微服务。一次用户请求穿越多个服务时,它可以完整还原调用链路,定位慢接口、报错节点,输出服务拓扑、吞吐量、延迟统计。 使用Agent探针采集数据,业务代码几乎不用改造,适合微服务故障排查与性能调优。

1.4 Elasticsearch(ES)

Elasticsearch 是分布式检索分析引擎。擅长存储海量半结构化数据,提供快速检索、聚合统计。 在这套监控场景下,主要用来存放SkyWalking产生的链路、追踪明细数据,方便故障复盘回溯。

2 两套监控方案对比

Prometheus+Grafana偏向宏观指标监控;SkyWalking+Elasticsearch偏向链路追踪与故障溯源。下表从核心功能、数据收集、可视化、应用场景做横向对比。

对比维度 Prometheus + Grafana SkyWalking + Elasticsearch
核心功能 时序指标监控;资源、业务指标、告警、趋势统计;看系统整体水位。没有链路追踪能力,看不到单次请求完整调用流程。 分布式链路追踪、APM性能剖析;还原完整请求链路,定位慢调用、报错节点;存储海量链路明细。通用指标能力偏弱。
数据收集方式 Pull拉取模式;被监控端暴露/metrics接口;通过各类Exporter对接MySQL、中间件、K8s;无代码侵入,集中式采集。 Push推送模式;应用挂载Agent探针采集链路数据,上报OAP服务,最终存入ES;几乎零代码侵入,应用侧埋点采集。
可视化能力 Grafana驱动,能力极强;自定义面板、模板变量、海量社区模板,大屏友好。 SkyWalking自带UI,提供拓扑、链路视图;可对接Kibana查看ES原始数据;自定义报表灵活性弱于Grafana。
适用场景 服务器/容器资源监控、业务指标大盘、日常巡检、资源告警、K8s全局监控;适合常态化运维。 微服务故障排查、慢请求定位、调用关系梳理、线上偶发问题溯源;适合排障、性能优化。

3 Prometheus+Grafana工作流程与Docker部署实操

3.1 工作流程图

graph LR A[被监控服务/服务器] -- 暴露metrics接口 --> B[Prometheus] C[MySQL数据库] -- MySQL Exporter输出指标 --> B B[Prometheus] -- 写入时序数据 --> D[本地时序存储] B -- 查询接口输出指标 --> E[Grafana] E -- 渲染图表 --> F[用户浏览器] B -- 匹配告警规则 --> G[告警通知]

3.2 环境说明

  • 操作系统:Ubuntu Server 20.04 / 22.04
  • 运行环境:Docker + Docker Compose
  • 组件:Prometheus、Grafana、mysql‑exporter(监控MySQL)

3.3 创建目录

1
2
mkdir -p /data/prometheus-grafana/{prometheus,exporter-mysql,grafana}
cd /data/prometheus-grafana

3.4 配置文件

3.4.1 prometheus/prometheus.yml

路径:/data/prometheus-grafana/prometheus/prometheus.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
global:
scrape_interval: 15s
evaluation_interval: 15s

rule_files:
# - "alert.rules.yml" # 需要告警时打开

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']

3.4.2 docker‑compose.yml

路径:/data/prometheus-grafana/docker-compose.yml > 修复:把废弃version: '3.8'去掉,新版compose不需要;增加持久化权限说明;密码请按需修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: prometheus
restart: always
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention=7d'
ports:
- "9090:9090"
networks:
- monitor-net

mysql-exporter:
image: prom/mysqld-exporter:v0.15.1
container_name: mysql-exporter
restart: always
environment:
DATA_SOURCE_NAME: "root:123456@tcp(192.168.1.100:3306)/"
ports:
- "9104:9104"
networks:
- monitor-net

grafana:
image: grafana/grafana:11.2.0
container_name: grafana
restart: always
volumes:
- ./grafana/data:/var/lib/grafana
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: admin123456
networks:
- monitor-net

networks:
monitor-net:
driver: bridge

3.5 启动与初始化

1
2
3
4
5
# grafana目录权限处理
sudo chown -R 472:472 ./grafana/data

docker compose up -d
docker compose ps

访问地址: - Prometheus:http://服务器IP:9090 - Grafana:http://服务器IP:3000 账号admin,密码admin123456

Grafana操作:添加数据源选择Prometheus,地址填http://prometheus:9090,测试连通成功后导入社区Dashboard模板即可出大盘。

4 SkyWalking+Elasticsearch工作流程与Docker部署实操

4.1 工作流程图

graph LR A[微服务应用] -- Agent探针上报链路数据 --> B[SkyWalking OAP服务] B[OAP服务] -- 清洗聚合 --> C[Elasticsearch存储] B -- 对外提供API --> D[SkyWalking UI] D -- 拓扑/链路/报表 --> E[用户浏览器] C[ES] -- 原始链路检索 --> D

4.2 环境说明

  • 操作系统:Ubuntu Server 20.04 / 22.04
  • 运行环境:Docker + Docker Compose
  • 组件:Elasticsearch7.17.0、SkyWalking OAP‑Server 9.5.0、SkyWalking‑UI 9.5.0

4.3 创建目录

1
2
mkdir -p /data/skywalking-es/{es-data,oap-config,ui-config}
cd /data/skywalking-es

4.4 docker‑compose.yml

路径:/data/skywalking-es/docker-compose.yml > ES单节点模式,内存调小适合测试环境;生产环境需要集群。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: elasticsearch
restart: always
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
- xpack.security.enabled=false
volumes:
- ./es-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
- "9300:9300"
networks:
- sky-net

skywalking-oap:
image: apache/skywalking-oap-server:9.5.0
container_name: skywalking-oap
restart: always
depends_on:
- elasticsearch
environment:
SW_STORAGE: elasticsearch
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
ports:
- "11800:11800"
- "12800:12800"
networks:
- sky-net

skywalking-ui:
image: apache/skywalking-ui:9.5.0
container_name: skywalking-ui
restart: always
depends_on:
- skywalking-oap
environment:
SW_OAP_ADDRESS: http://skywalking-oap:12800
ports:
- "8081:8080"
networks:
- sky-net

networks:
sky-net:
driver: bridge

4.5 权限与启动

ES容器内部用户uid=1000,宿主机目录必须授权,否则启动失败。

1
2
3
4
sudo chmod 777 -R ./es-data

docker compose up -d
docker compose ps

访问地址: - Elasticsearch:http://服务器IP:9200 - SkyWalking UI:http://服务器IP:8081

使用:业务程序配置SkyWalking Agent探针,启动应用上报数据,UI即可看到服务拓扑、调用链路、异常信息,链路数据持久化到ES。

5 总结

两套方案不是互斥替代,而是互补。 Prometheus+Grafana作为指标监控底座,负责日常资源、业务指标巡检与告警;SkyWalking+ES做链路追踪,负责微服务故障定位、性能调优。真实生产环境一般两套一起部署,同时拿到指标大盘与链路排障能力。


常见踩坑清单

1 Elasticsearch 启动失败

1.1 容器反复重启,日志提示权限 denied

  • 现象docker compose ps看到elasticsearch状态为Restarting;日志输出Permission denied
  • 根因:ES容器内部运行用户UID=1000,宿主机挂载目录es-data权限不足,无法写入数据文件。
  • 解决
    1
    2
    # 进入compose所在目录执行
    sudo chmod 777 -R ./es-data
    > 生产环境不建议777;测试环境快速调试可用;生产应当修改目录属主 sudo chown -R 1000:1000 ./es-data

1.2 ES启动报内存溢出、OOM被杀

  • 现象:容器刚启动直接退出;dmesg能看到OOM killer杀掉进程
  • 根因:机器内存太小,ES堆内存配置过大;机器低于2G内存极易复现。
  • 解决 修改compose中ES环境变量,降低堆大小
    1
    2
    environment:
    - ES_JAVA_OPTS=-Xms256m -Xmx256m
    > ES要求 Xms 与 Xmx保持一致;测试环境最小256M,生产建议至少1G以上。

1.3 ES单节点报错 discovery.type 未配置

  • 现象:日志报 master not discovered;集群无法形成,一直重启
  • 根因:单机部署忘记配置discovery.type=single-node,ES默认试图找集群其他节点。
  • 解决 compose elasticsearch service环境必须带上:
    1
    - discovery.type=single-node

1.4 vm.max_map_count 系统参数不足(Linux经典坑)

  • 现象:ES启动日志 max virtual memory areas vm.max_map_count [65530] is too low
  • 根因:Linux系统默认虚拟内存映射数不够,ES需要更大。
  • 临时生效(重启机器失效)
    1
    sudo sysctl -w vm.max_map_count=262144
  • 永久生效
    1
    2
    echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p

2 SkyWalking Agent 连不上 OAP服务

Agent运行在业务应用侧,OAP运行在docker容器内,这个坑出现频率很高。

2.1 Agent报错:connect to oap 11800 timeout / connection refused

  • 现象:应用日志大量warn,Agent无法上报数据;SkyWalking UI看不到任何服务。
  • 根因分类
  1. Agent配置的OAP地址写错;
  2. 防火墙/安全组没有放行11800端口(gRPC上报端口);12800是UI调用HTTP端口,Agent不走12800;
  3. 业务应用不在docker网络内,填容器内部主机名skywalking‑oap无法解析,必须填写宿主机IP。
  • 解决步骤
  1. Agent配置agent.configcollector.backend_service 填写宿主机IP:11800,不要填容器名;
    1
    collector.backend_service=192.168.1.100:11800
  2. 服务器防火墙放行11800端口;云服务器安全组放行11800;
  3. 在业务机器上验证连通:telnet 192.168.1.100 11800 或者 nc -zv 192.168.1.100 11800,必须通。

2.2 OAP还没就绪,Agent就开始上报

  • 现象:OAP刚启动几十秒内,Agent报连接失败;等待一段时间自动恢复。
  • 根因:OAP启动需要初始化ES索引,启动慢;docker compose的depends_on只保证容器启动顺序,不保证服务就绪。
  • 解决:业务应用晚几分钟启动;开发环境可以忽略;生产增加健康检查。

2.3 Agent版本和OAP版本不一致

  • 现象:连接可以通,但是无数据,报序列化异常。
  • 根因:SkyWalking Agent版本号必须和后端OAP版本严格对齐;例如OAP 9.5.0,Agent也必须9.5.0。跨版本会出现协议不兼容。
  • 解决:保持Agent、OAP‑Server、UI三者版本完全一致。

2.4 ES异常导致OAP工作异常,间接Agent上报失败

  • 现象:Agent显示上报成功,但UI看不到链路;OAP日志大量ES报错。
  • 根因:OAP虽然gRPC端口通,但无法写入ES,数据直接丢弃。
  • 排查:查看docker compose logs skywalking-oap,看ES相关报错;优先保证ES正常运行。

3 Grafana 数据源连通异常(对接Prometheus)

3.1 Save & test 报错:connection refused

  • 现象:Grafana页面添加Prometheus数据源,填写地址,测试报错连接拒绝。
  • 根因区分
  1. 127.0.0.1:9090:Grafana跑在docker容器内部,127.0.0.1指向Grafana容器自己,不是宿主机prometheus。
  2. 填宿主机IP,但防火墙/安全组拦截9090。
  3. 网络问题:没有使用compose内部网络,容器之间无法互通。
  • 正确写法: > 在同一个docker compose网络monitor‑net内部,直接写容器名:
    1
    http://prometheus:9090
    > 如果Grafana不在同一个compose,填写宿主机真实IP:9090,并且确认防火墙放行9090。

3.2 可以连通,但面板无数据

  • 现象:数据源测试成功,导入Dashboard后图表空白。
  • 根因
  1. Prometheus scrape_configs job采集失败;targets页面显示DOWN;
  2. Dashboard模板选择时间范围不对;
  3. 使用的PromQL指标名称和exporter输出指标不匹配。
  • 排查 打开Prometheus页面 Status → Targets,查看各个job状态;如果target显示DOWN,检查exporter配置。

3.3 mysql‑exporter连接MySQL失败,采集不到MySQL指标

  • 现象:Prometheus target中mysql job UP,但无mysql相关指标。
  • 根因DATA_SOURCE_NAME账号密码、MySQL地址错误;MySQL账号没有授权访问。 > 注意:DATA_SOURCE_NAME=root:123456@tcp(192.168.1.100:3306)/ 不要加多余空格。
  • 验证exporter是否正常:浏览器访问 http://宿主机IP:9104/metrics,看是否输出大量mysql指标。输出为空说明exporter连不上数据库。

4 其他通用小坑

  1. docker compose v1/v2命令差异:新版是docker compose up -d(无短横线);老版本docker‑compose up -d
  2. 容器重建后数据丢失:确认volumes挂载路径正确,不要挂载容器内部临时路径。
  3. Prometheus数据保留时间:storage.tsdb.retention=7d默认7天;磁盘紧张注意调小。

微服务可观测性:两套主流监控方案对比与Docker落地实操
https://jycpp.github.io/2024/24-06-10-两套主流监控方案对比和部署实操.html
作者
Jet Yan
发布于
2024年6月10日
许可协议