black flat screen tv showing game

跑着量化策略和代理节点的服务器,没有监控是非常危险的。凌晨内存爆了、磁盘满了、策略挂了——如果没有告警,可能几个小时后才发现。

这篇文章从零开始,搭建一套完整的监控系统:被监控机器上跑 Node Exporter 采集指标,Prometheus 收集存储,Grafana 可视化展示,加上 Telegram 告警。

架构说明

被监控 VPS(N台)          监控中心 VPS(1台)
┌──────────────┐          ┌─────────────────────┐
│ Node Exporter │ ──9100→ │ Prometheus(采集)   │
│ Node Exporter │ ──9100→ │ Grafana(展示)      │
│ Node Exporter │ ──9100→ │ Alertmanager(告警) │
└──────────────┘          └─────────────────────┘

我的做法:一台小 VPS(1核1G 足够)作为监控中心,其他机器装 Node Exporter 暴露指标。

第一步:在被监控机器上安装 Node Exporter

每台要监控的 VPS 都要做这一步。

# 下载 Node Exporter(确认最新版本号)
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
mv node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/

创建 systemd 服务:

cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/local/bin/node_exporter --web.listen-address=:9100
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable node_exporter --now

验证是否正常运行:

curl http://localhost:9100/metrics | head -20
# 看到大量指标输出说明正常

防火墙设置:

Node Exporter 的 9100 端口只需要让 Prometheus 服务器访问,不要对公网开放:

# 只允许监控中心 IP 访问 9100
ufw allow from 监控中心IP to any port 9100
# 不要执行 ufw allow 9100  ← 这会对所有人开放

第二步:在监控中心安装 Prometheus

这台服务器负责主动拉取所有机器的指标。

# 创建专用用户
useradd --no-create-home --shell /bin/false prometheus

# 下载 Prometheus
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.51.2/prometheus-2.51.2.linux-amd64.tar.gz
tar xzf prometheus-2.51.2.linux-amd64.tar.gz

# 安装
mkdir -p /etc/prometheus /var/lib/prometheus
cp prometheus-2.51.2.linux-amd64/prometheus /usr/local/bin/
cp prometheus-2.51.2.linux-amd64/promtool /usr/local/bin/
cp -r prometheus-2.51.2.linux-amd64/consoles /etc/prometheus/
cp -r prometheus-2.51.2.linux-amd64/console_libraries /etc/prometheus/

chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus

创建配置文件 /etc/prometheus/prometheus.yml:

global:
  scrape_interval: 30s      # 每 30 秒采集一次
  evaluation_interval: 30s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['localhost:9093']

rule_files:
  - /etc/prometheus/rules/*.yml

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets:
          - 'aws-hk-IP:9100'     # 香港节点
          - 'aws-us-IP:9100'     # 美国节点
          - 'aws-jp-IP:9100'     # 日本节点
          - 'dmit-us-IP:9100'    # DMIT 美国
        labels:
          env: 'production'

创建 systemd 服务:

cat > /etc/systemd/system/prometheus.service << 'EOF'
[Unit]
Description=Prometheus
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=:9090
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable prometheus --now

访问 http://监控中心IP:9090 验证,在 Status → Targets 里能看到所有被监控机器的状态。

第三步:安装 Grafana

# 添加 Grafana APT 源
apt-get install -y apt-transport-https software-properties-common
wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | \
  tee /etc/apt/sources.list.d/grafana.list

apt-get update
apt-get install -y grafana

systemctl enable grafana-server --now

Grafana 默认跑在 3000 端口,访问 http://监控中心IP:3000:

  • 默认账号:admin
  • 默认密码:admin(登录后会要求修改)

添加 Prometheus 数据源

  1. 左侧菜单 → Connections → Data sources
  2. 点 Add data source → 选 Prometheus
  3. URL 填 http://localhost:9090
  4. 点 Save & test,显示"Data source is working"即成功

导入现成 Dashboard

不用自己画图,直接导入社区的成熟 Dashboard:

  1. 左侧菜单 → Dashboards → Import
  2. 填入 Dashboard ID:1860(Node Exporter Full,最常用)
  3. 选择 Prometheus 数据源
  4. 点 Import

这个 Dashboard 包含:CPU 使用率、内存、磁盘 IO、网络流量、系统负载、文件系统空间,非常完整。

第四步:配置 Telegram 告警

光有图表不够,机器出问题要第一时间收到通知。

创建 Telegram Bot

  1. 在 Telegram 里找 @BotFather
  2. 发送 /newbot,给 bot 起名字
  3. 保存返回的 Bot Token(格式:1234567890:ABCD...)
  4. 给 bot 发一条消息,然后访问 https://api.telegram.org/bot你的TOKEN/getUpdates 获取 chat_id

安装 Alertmanager

cd /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xzf alertmanager-0.27.0.linux-amd64.tar.gz
cp alertmanager-0.27.0.linux-amd64/alertmanager /usr/local/bin/
mkdir -p /etc/alertmanager

创建 /etc/alertmanager/alertmanager.yml:

global:
  resolve_timeout: 5m

route:
  receiver: telegram
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

receivers:
  - name: telegram
    telegram_configs:
      - bot_token: '你的Bot Token'
        chat_id: 你的chat_id
        message: |
          🚨 告警:{{ .GroupLabels.alertname }}
          主机:{{ .GroupLabels.instance }}
          详情:{{ range .Alerts }}{{ .Annotations.description }}{{ end }}
        send_resolved: true
cat > /etc/systemd/system/alertmanager.service << 'EOF'
[Unit]
Description=Alertmanager
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/bin/alertmanager \
  --config.file=/etc/alertmanager/alertmanager.yml \
  --storage.path=/var/lib/alertmanager
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable alertmanager --now

配置告警规则

创建 /etc/prometheus/rules/node_alerts.yml:

groups:
  - name: node_alerts
    rules:
      # CPU 超过 85% 持续 5 分钟
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        annotations:
          description: "{{ $labels.instance }} CPU 使用率 {{ $value | printf \"%.1f\" }}%"

      # 内存可用低于 10%
      - alert: LowMemory
        expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 < 10
        for: 2m
        annotations:
          description: "{{ $labels.instance }} 可用内存仅剩 {{ $value | printf \"%.1f\" }}%"

      # 磁盘使用超过 85%
      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
        for: 5m
        annotations:
          description: "{{ $labels.instance }} 磁盘剩余 {{ $value | printf \"%.1f\" }}%"

      # 机器宕机(超过 2 分钟无法采集)
      - alert: InstanceDown
        expr: up == 0
        for: 2m
        annotations:
          description: "{{ $labels.instance }} 已离线超过 2 分钟"

重载配置:

systemctl reload prometheus
# 或者
curl -X POST http://localhost:9090/-/reload

第五步:用 Nginx 反向代理(安全访问)

不建议直接把 Grafana 的 3000 端口暴露到公网,用 Nginx 加一层:

apt install nginx -y

cat > /etc/nginx/sites-available/grafana << 'EOF'
server {
    listen 80;
    server_name grafana.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name grafana.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/grafana.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grafana.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF

ln -s /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

SSL 证书用 acme.sh 自动申请:

curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --issue -d grafana.yourdomain.com --nginx
~/.acme.sh/acme.sh --install-cert -d grafana.yourdomain.com \
  --cert-file /etc/letsencrypt/live/grafana.yourdomain.com/fullchain.pem \
  --key-file /etc/letsencrypt/live/grafana.yourdomain.com/privkey.pem \
  --reloadcmd "systemctl reload nginx"

效果展示

搭建完成后你能看到:

  • 每台机器的 CPU / 内存 / 磁盘实时曲线
  • 网络流量 in/out,清楚看到哪个节点在跑大流量
  • 系统负载趋势,量化策略重算时的压力一眼看出
  • 机器宕机或指标异常,Telegram 立刻收到告警

延伸阅读:


📷 封面图 · Flux Schnell AI 生成 · panshi.io 品牌风格