
跑著量化策略和代理節點的伺服器,沒有監控是非常危險的。凌晨記憶體爆了、磁碟滿了、策略掛了——如果沒有告警,可能幾個小時後才發現。
這篇文章從零開始,搭建一套完整的監控系統:被監控機器上跑 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 資料來源
- 左側選單 → Connections → Data sources
- 點 Add data source → 選 Prometheus
- URL 填
http://localhost:9090 - 點 Save & test,顯示"Data source is working"即成功
匯入現成 Dashboard
不用自己畫圖,直接匯入社群的成熟 Dashboard:
- 左側選單 → Dashboards → Import
- 填入 Dashboard ID:1860(Node Exporter Full,最常用)
- 選擇 Prometheus 資料來源
- 點 Import
這個 Dashboard 包含:CPU 使用率、記憶體、磁碟 IO、網路流量、系統負載、檔案系統空間,非常完整。
第四步:配置 Telegram 告警
光有圖表不夠,機器出問題要第一時間收到通知。
建立 Telegram Bot
- 在 Telegram 裡找
@BotFather - 傳送
/newbot,給 bot 起名字 - 儲存返回的 Bot Token(格式:
1234567890:ABCD...) - 給 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 品牌風格