欢迎光临
我们一直在努力

现代监控与可观测性体系实战:Prometheus + Grafana + Loki 从入门到生产部署

在云原生时代,监控与可观测性(Observability)已经成为后端工程师和运维人员的必备技能。传统的监控方案往往只关注服务器的 CPU、内存等基础指标,但在微服务架构和容器化部署日益普及的今天,我们需要一套更完整的可观测性体系来应对复杂的系统环境。

本文将带你从零搭建一套基于 Prometheus + Grafana + Loki 的现代监控体系,涵盖指标收集、可视化展示、日志聚合和告警配置,并分享生产环境部署的最佳实践。

一、可观测性的三大支柱

在深入技术实现之前,我们先理解可观测性的核心概念。现代可观测性体系通常包含三大支柱:

支柱 工具 解决的问题
Metrics(指标) Prometheus 系统性能趋势、异常检测
Logs(日志) Loki / ELK 事故根因分析、审计追踪
Traces(链路追踪) Jaeger / Tempo 请求链路分析、性能瓶颈定位

本文将重点覆盖 Metrics 和 Logs 两大支柱,它们也是日常运维中最常用的两部分。链路追踪我们会在后续文章中单独讨论。

二、Prometheus:指标收集与存储

Prometheus 是目前最流行的开源监控系统,它采用 Pull 模式从目标服务拉取指标数据,并内置了强大的时序数据库。它的核心优势在于:多维数据模型(基于标签)、灵活的 PromQL 查询语言,以及强大的告警能力。

2.1 安装 Prometheus

我们使用 Docker Compose 来部署整套监控栈,这是最快捷也最易于维护的方式。首先创建项目目录结构:


1
2
mkdir -p /opt/monitoring/{prometheus,grafana,loki,promtail}
cd /opt/monitoring

创建 docker-compose.yml:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:v2.50.1
    container_name: prometheus
    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.time=30d'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
    ports:
      - '9090:9090'
    restart: unless-stopped

volumes:
  prometheus_data:

2.2 Prometheus 配置文件详解

创建 prometheus/prometheus.yml:


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
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  scrape_timeout: 10s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093

rule_files:
  - 'rules/*.yml'

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

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['node_exporter:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

这里我们配置了三个抓取目标:Prometheus 自身、Node Exporter(服务器指标)、cAdvisor(容器指标)。scrape_interval: 15s 表示每15秒采集一次数据,retention.time=30d 表示数据保留30天。

2.3 PromQL 实战查询

PromQL 是 Prometheus 的查询语言,掌握它才能真正用好监控数据。以下是一些常用的查询示例:

CPU 使用率:


1
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

内存使用率:


1
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

磁盘使用率:


1
(node_filesystem_size_bytes{fstype!="tmpfs"} - node_filesystem_free_bytes{fstype!="tmpfs"}) / node_filesystem_size_bytes{fstype!="tmpfs"} * 100

HTTP 请求错误率:


1
rate(http_requests_total{status=~"5.."}[5m])

这些查询表达式可以直接在 Grafana 面板中使用,也可以用于配置告警规则。

三、Grafana:数据可视化与告警

Grafana 是目前最流行的开源数据可视化平台,它支持 Prometheus、Loki、Elasticsearch、InfluxDB 等数十种数据源。我们用它来创建监控仪表盘和配置告警规则。

3.1 部署 Grafana

在 docker-compose.yml 中添加 Grafana 服务:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  grafana:
    image: grafana/grafana:10.4.1
    container_name: grafana
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=Chang3Th!sPwd
      - GF_INSTALL_PLUGINS=grafana-piechart-panel
    ports:
      - '3000:3000'
    restart: unless-stopped

volumes:
  grafana_data:

Grafana 支持 Provisioning 机制,可以在启动时自动配置数据源和仪表盘,无需手动操作。创建 grafana/provisioning/datasources/prometheus.yml:


1
2
3
4
5
6
7
8
9
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false

3.2 创建高效的仪表盘

一个优秀的监控仪表盘应该遵循黄金信号原则——即 Google SRE 提出的四个关键指标:

  • 延迟(Latency):请求处理时间,关注 P50、P95、P99 分位数
  • 流量(Traffic):每秒请求数(RPS)、网络吞吐量
  • 错误(Errors):错误率、HTTP 5xx 比例
  • 饱和度(Saturation):CPU、内存、磁盘、连接数使用率

我们可以通过 Grafana 的变量功能实现动态切换:


1
2
# 定义变量 $instance,查询所有可用的实例标签
label_values(up, instance)

然后在面板中使用 $instance 变量,即可实现切换查看不同服务器的指标。

3.3 配置告警规则

告警是可观测性体系中至关重要的一环。Grafana 内置了强大的告警引擎,支持多种通知渠道:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Grafana 告警规则示例(通过 API 或 UI 配置)
apiVersion: 1
groups:
  - name: server_alerts
    interval: 30s
    rules:
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }} CPU 使用率超过 80%"
          description: "当前 CPU 使用率: {{ $value | humanizePercentage }}"

      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < 0.1
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.instance }} 磁盘空间不足"
          description: "可用磁盘空间小于 10%"

告警通知渠道可以配置为钉钉、企业微信、Slack、邮件等。这里以钉钉为例:


1
2
3
# 在 Grafana 中配置钉钉通知
# 设置 -> 通知渠道 -> 添加 -> DingDing
# Webhook URL: https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN

需要注意的是,告警频率不宜过高,对于瞬时的抖动可以设置 for: 5m 来避免误报。

四、Loki:轻量级日志聚合

Loki 是 Grafana Labs 推出的日志聚合系统,灵感来自 Prometheus,采用相同的标签体系。与 ELK 相比,Loki 最大的优势在于:它不全文索引日志内容,而是只索引标签,因此存储成本更低,查询速度也更快。

4.1 部署 Loki


1
2
3
4
5
6
7
8
9
10
  loki:
    image: grafana/loki:2.9.4
    container_name: loki
    volumes:
      - ./loki/loki-config.yml:/etc/loki/loki-config.yml
      - loki_data:/loki
    ports:
      - '3100:3100'
    command: -config.file=/etc/loki/loki-config.yml
    restart: unless-stopped

创建 loki/loki-config.yml:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1

schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

4.2 Promtail:日志采集器

Promtail 是 Loki 官方的日志采集代理,负责从各个节点收集日志并发送到 Loki:


1
2
3
4
5
6
7
8
9
10
11
  promtail:
    image: grafana/promtail:2.9.4
    container_name: promtail
    volumes:
      - ./promtail/promtail-config.yml:/etc/promtail/promtail-config.yml
      - /var/log:/var/log
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
    command: -config.file=/etc/promtail/promtail-config.yml
    restart: unless-stopped
    depends_on:
      - loki

创建 promtail/promtail-config.yml:


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
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          __path__: /var/log/*.log

  - job_name: containers
    pipeline_stages:
      - docker: {}
    static_configs:
      - targets:
          - localhost
        labels:
          job: docker
          __path__: /var/lib/docker/containers/*/*-json.log

这里配置了两个采集任务:系统日志(/var/log/*.log)和容器日志(Docker JSON 日志)。每个日志条目都会自动带上 job 标签,方便在 Grafana 中筛选。

4.3 LogQL 日志查询

LogQL 是 Loki 的查询语言,语法与 PromQL 类似。以下是一些常用查询:

查询 Nginx 错误日志:


1
{job="varlogs", filename="/var/log/nginx/error.log"} |= "error"

查询特定容器的日志:


1
{job="docker", container="my-app"} |= "ERROR" | json | line_format "{{.message}}"

统计错误率:


1
rate({job="docker", container="api-server"} |= "HTTP 5" [5m])

Grafana 的 Explore 面板是调试日志的最佳工具,可以实时查看和过滤日志流。

五、Node Exporter + cAdvisor:全面采集服务器指标

仅有 Prometheus 还不够,我们需要额外的采集器来获取服务器和容器的详细指标。

5.1 Node Exporter

Node Exporter 是 Prometheus 官方的服务器指标采集器,可以收集 CPU、内存、磁盘、网络等上百种指标:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  node_exporter:
    image: prom/node-exporter:v1.7.0
    container_name: node_exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--path.rootfs=/rootfs'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    ports:
      - '9100:9100'
    restart: unless-stopped

5.2 cAdvisor

cAdvisor 是 Google 开源的容器监控工具,可以采集每个容器的资源使用情况:


1
2
3
4
5
6
7
8
9
10
11
12
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.49.1
    container_name: cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    ports:
      - '8080:8080'
    restart: unless-stopped

部署完成后,访问 http://服务器IP:9100/metrics 和 http://服务器IP:8080/metrics 即可看到采集到的原始指标数据。

六、生产环境部署最佳实践

经过前面的步骤,我们已经搭建了一套完整的监控体系。但在生产环境中,还需要注意以下几点:

6.1 数据持久化与备份

Prometheus 和 Loki 的数据都存储在 Docker 卷中,建议定期备份:


1
2
3
4
5
6
7
# 备份 Prometheus 数据
# 可以使用 Prometheus 的快照 API 实现热备份
curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot

# 备份 Loki 数据
# 直接备份 /loki/chunks 和 /loki/index 目录
tar czf loki_backup_$(date +%Y%m%d).tar.gz /var/lib/docker/volumes/monitoring_loki_data/_data

6.2 高可用部署

对于关键业务系统,建议部署高可用架构:

  • Prometheus 高可用:部署两个 Prometheus 实例,使用相同的抓取配置,配合 Thanos 实现全局视图
  • Grafana 高可用:使用共享数据库(MySQL/PostgreSQL)存储配置,多实例部署
  • Loki 高可用:使用对象存储(S3/MinIO)作为后端存储,部署多个 Loki 微服务组件

6.3 资源限制与性能调优


1
2
3
4
5
6
7
8
9
10
11
# 限制 Prometheus 内存使用
--storage.tsdb.retention.time=30d  # 保留30天
--storage.tsdb.retention.size=50GB  # 最大50GB

# Loki 性能优化
# 在 loki-config.yml 中配置
chunk_target_size: 1536000  # 1.5MB
max_chunk_age: 2h

# 限制 Grafana 日志级别
GF_LOG_LEVEL=warn

6.4 安全加固

监控系统本身不能成为安全短板:

  • 为 Grafana 配置 HTTPS 和反向代理(Nginx)
  • 使用强密码,开启 Grafana 的 OAuth 或 LDAP 认证
  • Prometheus 和 Loki 的管理接口不要暴露在公网
  • 使用 Prometheus 的 Basic Auth 或 OAuth2 保护抓取端点和查询接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Nginx 反向代理 Grafana 示例
server {
    listen 443 ssl;
    server_name monitor.example.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

七、总结与下一步

本文从零搭建了一套完整的可观测性体系,涵盖了 Prometheus 指标收集、Grafana 可视化与告警、Loki 日志聚合三大核心组件。这套方案完全开源、社区活跃、生态丰富,适合中小型团队快速落地。

下一步可以探索的方向:

  • 链路追踪:接入 Jaeger 或 Grafana Tempo,实现分布式请求追踪
  • 告警收敛:使用 Alertmanager 的抑制和分组功能,减少告警噪音
  • 自定义 Exporter:为业务指标编写自定义 Prometheus Exporter
  • Thanos 集群:实现跨集群的全局监控视图和长期存储
  • Kubernetes 集成:使用 kube-prometheus-stack Helm Chart 在 K8s 中一键部署

如果你在搭建过程中遇到任何问题,欢迎在评论区留言交流。监控体系的建设是一个持续优化的过程,希望本文能帮你迈出第一步。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 现代监控与可观测性体系实战:Prometheus + Grafana + Loki 从入门到生产部署
分享到: 更多 (0)