比特幣節點監控完整指南
深入介紹如何自建比特幣節點的監控系統,涵蓋腳本自動化、警報設定和儀表板建置。
比特幣節點監控完整指南
深入介紹如何自建比特幣節點的監控系統,涵蓋腳本自動化、警報設定和儀表板建置。
監控概述
為何需要監控比特幣節點?
| 監控項目 | 重要性 | 影響 |
|---|---|---|
| 同步狀態 | 高 | 節點可能落後攻擊 |
| 連接數 | 中 | 網路連接問題 |
| 記憶體使用 | 高 | OOM 當機 |
| 磁碟空間 | 高 | 同步失敗 |
| 區塊高度 | 高 | 確認交易狀態 |
基本監控腳本
Shell 監控腳本
節點狀態檢查
#!/bin/bash
# bitcoin-monitor.sh
RPC_USER="your-user"
RPC_PASS="your-password"
RPC_PORT="8332"
HOST="127.0.0.1"
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 獲取節點資訊
get_info() {
curl -s -u ${RPC_USER}:${RPC_PASS} \
-X POST \
-H "content-type: text/plain;" \
--data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": []}' \
http://${HOST}:${RPC_PORT}/ | jq -r '.result'
}
# 檢查節點狀態
check_status() {
INFO=$(get_info)
if [ "$INFO" = "null" ]; then
echo -e "${RED}✗ 節點無回應${NC}"
exit 1
fi
BLOCKS=$(echo "$INFO" | jq -r '.blocks')
HEADERS=$(echo "$INFO" | jq -r '.headers')
SYNCED=$(echo "$INFO" | jq -r '.initialblockdownload')
echo "=== 比特幣節點狀態 ==="
echo "區塊高度: $BLOCKS"
echo "標題數量: $HEADERS"
if [ "$SYNCED" = "true" ]; then
echo -e "同步狀態: ${GREEN}已完成${NC}"
else
echo -e "同步狀態: ${YELLOW}同步中${NC}"
fi
}
# 檢查連接數
check_connections() {
CONNECTIONS=$(curl -s -u ${RPC_USER}:${RPC_PASS} \
-X POST \
-H "content-type: text/plain;" \
--data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getconnectioncount", "params": []}' \
http://${HOST}:${RPC_PORT}/ | jq -r '.result')
echo "連接數: $CONNECTIONS"
if [ "$CONNECTIONS" -lt 8 ]; then
echo -e "${RED}⚠ 連接數過低${NC}"
fi
}
# 檢查記憶體
check_memory() {
MEM=$(free -m | grep Mem | awk '{print $3}')
MEM_TOTAL=$(free -m | grep Mem | awk '{print $2}')
MEM_PERCENT=$((MEM * 100 / MEM_TOTAL))
echo "記憶體使用: ${MEM}MB / ${MEM_TOTAL}MB (${MEM_PERCENT}%)"
if [ "$MEM_PERCENT" -gt 90 ]; then
echo -e "${RED}⚠ 記憶體使用過高${NC}"
fi
}
# 檢查磁碟空間
check_disk() {
DISK=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
echo "磁碟使用: ${DISK}%"
if [ "$DISK" -gt 85 ]; then
echo -e "${RED}⚠ 磁碟空間不足${NC}"
fi
}
# 執行所有檢查
check_status
check_connections
check_memory
check_disk
自動化排程
# 編輯 crontab
crontab -e
# 每 5 分鐘執行一次監控
*/5 * * * * /path/to/bitcoin-monitor.sh >> /var/log/bitcoin-monitor.log 2>&1
Python 監控腳本
#!/usr/bin/env python3
# bitcoin_monitor.py
import requests
import json
import time
from datetime import datetime
class BitcoinNodeMonitor:
def __init__(self, rpc_user, rpc_pass, host='127.0.0.1', port=8332):
self.url = f"http://{host}:{port}/"
self.auth = (rpc_user, rpc_pass)
self.session = requests.Session()
self.session.auth = self.auth
def rpc_call(self, method, params=None):
payload = {
"jsonrpc": "1.0",
"id": "monitor",
"method": method,
"params": params or []
}
response = self.session.post(
self.url,
json=payload,
headers={"content-type": "text/plain"}
)
return response.json()["result"]
def get_blockchain_info(self):
return self.rpc_call("getblockchaininfo")
def get_network_info(self):
return self.rpc_call("getnetworkinfo")
def get_mempool_info(self):
return self.rpc_call("getmempoolinfo")
def check_health(self):
"""完整健康檢查"""
results = {
"timestamp": datetime.now().isoformat(),
"blockchain": self.get_blockchain_info(),
"network": self.get_network_info(),
"mempool": self.get_mempool_info()
}
# 檢查同步狀態
if results["blockchain"]["initialblockdownload"]:
results["status"] = "syncing"
elif results["blockchain"]["blocks"] == results["blockchain"]["headers"]:
results["status"] = "synced"
else:
results["status"] = "error"
# 檢查連接數
results["connections_ok"] = results["network"]["connections"] >= 8
return results
def get_peer_info(self):
return self.rpc_call("getpeerinfo")
def get_block_stats(self, block_hash_or_height):
return self.rpc_call("getblockstats", [block_hash_or_height])
if __name__ == "__main__":
monitor = BitcoinNodeMonitor("rpcuser", "rpcpass")
health = monitor.check_health()
print(json.dumps(health, indent=2))
警報系統
Telegram 警報
#!/usr/bin/env python3
# alert_system.py
import requests
import json
class AlertManager:
def __init__(self, telegram_bot_token, telegram_chat_id):
self.bot_token = telegram_bot_token
self.chat_id = telegram_chat_id
self.api_url = f"https://api.telegram.org/bot{self.bot_token}"
def send_alert(self, message, parse_mode="Markdown"):
"""發送 Telegram 訊息"""
url = f"{self.api_url}/sendMessage"
data = {
"chat_id": self.chat_id,
"text": message,
"parse_mode": parse_mode
}
return requests.post(url, json=data).json()
def send_photo(self, photo_path, caption):
"""發送圖片"""
url = f"{self.api_url}/sendPhoto"
files = {"photo": open(photo_path, "rb")}
data = {"chat_id": self.chat_id, "caption": caption}
return requests.post(url, files=files, data=data).json()
# 警報範例
def check_and_alert(monitor):
health = monitor.check_health()
# 檢查同步狀態
if health["status"] != "synced":
alert_mgr = AlertManager("BOT_TOKEN", "CHAT_ID")
alert_mgr.send_alert(
f"⚠️ *比特幣節點警報*\n\n"
f"狀態: {health['status']}\n"
f"區塊: {health['blockchain']['blocks']}\n"
f"落後: {health['blockchain']['headers'] - health['blockchain']['blocks']} 區塊"
)
# 檢查連接數
if not health["connections_ok"]:
alert_mgr = AlertManager("BOT_TOKEN", "CHAT_ID")
alert_mgr.send_alert(
f"⚠️ *連接數過低*\n\n"
f"連接數: {health['network']['connections']}\n"
f"需要至少 8 個連接"
)
Email 警報
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
class EmailAlerts:
def __init__(self, smtp_server, smtp_port, username, password, from_addr):
self.smtp_server = smtp_server
self.smtp_port = smtp_port
self.username = username
self.password = password
self.from_addr = from_addr
def send_email(self, to_addr, subject, body):
msg = MIMEMultipart()
msg["From"] = self.from_addr
msg["To"] = to_addr
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
server.starttls()
server.login(self.username, self.password)
server.send_message(msg)
監控腳本整合
#!/bin/bash
# monitor-with-alerts.sh
RPC_USER="your-user"
RPC_PASS="your-password"
LOG_FILE="/var/log/bitcoin-monitor.log"
ALERT_SCRIPT="/path/to/alert_system.py"
# 記錄函數
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 檢查節點狀態
CHECK=$(curl -s -u ${RPC_USER}:${RPC_PASS} \
-X POST \
-H "content-type: text/plain;" \
--data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": []}' \
http://127.0.0.1:8332/ | jq -r '.result.blocks')
if [ "$CHECK" = "null" ]; then
log "ERROR: 節點無回應"
python3 $ALERT_SCRIPT "node_down" "比特幣節點無回應!"
exit 1
fi
log "OK: 節點正常,高度 $CHECK"
監控儀表板
Prometheus + Grafana
Prometheus 配置
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'bitcoin-node'
static_configs:
- targets: ['localhost:9100'] # node_exporter
metrics_path: /metrics
Grafana 儀表板 JSON
{
"dashboard": {
"title": "比特幣節點監控",
"panels": [
{
"title": "區塊高度",
"type": "stat",
"targets": [
{
"expr": "bitcoin_blocks"
}
]
},
{
"title": "連接數",
"type": "graph",
"targets": [
{
"expr": "bitcoin_connections"
}
]
},
{
"title": "記憶體使用",
"type": "gauge",
"targets": [
{
"expr": "bitcoin_memory_percent"
}
]
}
]
}
}
開源監控工具
| 工具 | 用途 | 優點 |
|---|---|---|
| Prometheus | 指標收集 | 功能強大 |
| Grafana | 視覺化 | 靈活儀表板 |
| Netdata | 即時監控 | 易於部署 |
| Zabbix | 企業級監控 | 完整功能 |
進階監控指標
節點健康指標
def calculate_node_score(health):
"""計算節點健康分數"""
score = 100
# 同步狀態扣分
if health["status"] != "synced":
score -= 30
# 連接數扣分
connections = health["network"]["connections"]
if connections < 8:
score -= 20
elif connections < 10:
score -= 10
# 記憶體扣分
mem_percent = health.get("memory_percent", 0)
if mem_percent > 90:
score -= 20
elif mem_percent > 80:
score -= 10
# 磁碟扣分
disk_percent = health.get("disk_percent", 0)
if disk_percent > 90:
score -= 20
return max(0, score)
異常檢測
def detect_anomalies(metrics_history):
"""檢測異常"""
anomalies = []
# 檢查區塊高度變化
if len(metrics_history) > 2:
recent_blocks = [m["blocks"] for m in metrics_history[-3:]]
if len(set(recent_blocks)) == 1:
anomalies.append("區塊高度停滞")
# 檢查連接數驟降
if len(metrics_history) > 1:
prev_conn = metrics_history[-2]["network"]["connections"]
curr_conn = metrics_history[-1]["network"]["connections"]
if prev_conn - curr_conn > 5:
anomalies.append(f"連接數驟降: {prev_conn} -> {curr_conn}")
return anomalies
自動化維護腳本
磁碟空間管理
#!/bin/bash
# cleanup.sh
# 清理舊區塊(保留最新 100GB)
bitcoin-cli -rpcwallet= pruneblockchain 100000
# 清理日誌
find /var/log -name "bitcoin*.log" -mtime +7 -delete
# 清理調試日誌
rm -rf ~/.bitcoin/logs/*.log
節點重啟腳本
#!/bin/bash
# restart-node.sh
SYSTEMD_SERVICE="bitcoind"
# 檢查服務狀態
if systemctl is-active --quiet $SYSTEMD_SERVICE; then
echo "節點運行中,重啟中..."
systemctl restart $SYSTEMD_SERVICE
sleep 30
# 驗證重啟成功
if bitcoin-cli getblockcount > /dev/null 2>&1; then
echo "節點重啟成功"
else
echo "節點重啟失敗,發送警報"
fi
else
echo "節點未運行,啟動中..."
systemctl start $SYSTEMD_SERVICE
fi
常見問題排查
問題:節點落後
解決方案:
- 檢查網路連接
- 增加 maxconnections
- 檢查頻寬
- 考慮使用更快磁碟
問題:記憶體不足
解決方案:
- 減少 dbcache
- 減少 maxconnections
- 使用 swap
- 升級硬體
問題:磁碟空間不足
解決方案:
- 啟用 prune 模式
- 清理舊區塊
- 遷移到更大磁碟
總結
比特幣節點監控是確保網路安全和服務穩定的關鍵。透過本文介紹的工具和腳本,您可以:
- ✅ 即時掌握節點狀態
- ✅ 及時發現異常問題
- ✅ 自動化維護流程
- ✅ 建立完善警報系統
相關連結
相關文章
- Bitcoin Core 節點運作 — 運行完整節點,理解比特幣網路的運作機制。
- 比特幣節點監控與告警設定 — 使用腳本與工具監控節點狀態、連線數與區塊同步。
- Taproot 全面解析 — 比特幣最新的腳本升級:MAST、BIP-340/341/342。
- 比特幣節點安全強化指南 — 防火牆設定、安全儲存與節點隔離的實作建議。
- Drivechains 側鏈:比特幣側鏈擴展方案的深度解析 — 深入分析 Drivechain 技術原理、Hash Rate Escrow 機制、安全性分析與實際應用場景,探討其與 Liquid、RSK 等側鏈方案的比較。
延伸閱讀與來源
這篇文章對您有幫助嗎?
請告訴我們如何改進:
0 人覺得有帮助
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!