引言
对于使用按流量计费或有限流量套餐的 VPS 用户来说,带宽超支是最常见的意外账单来源之一。无论是 DigitalOcean、Vultr 还是 Linode,超出套餐流量的费用可能远超你的预期。本文将介绍一套完整的流量监控和省钱方案,帮助你轻松掌控 VPS 带宽使用情况。
为什么需要流量监控?
大多数 VPS 套餐提供一定的免费流量额度(如 1TB/月),超出后按 GB 计费。对于运行网站、API 服务或文件下载的 VPS,流量消耗可能迅速增长:
- 静态网站:日均 1000 PV 约消耗 5-10GB
- 视频/文件下载:一个热门文件被下载 100 次就可能耗尽月度配额
- API 服务:高频调用可能产生意想不到的流量消耗
- DDoS 攻击:未防护的 VPS 可能在几小时内消耗大量流量
方案一:使用 Prometheus + Node Exporter 实时监控
安装 Node Exporter
# 创建 node_exporter 用户
sudo useradd --no-create-home --shell /bin/false node_exporter
# 下载安装
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvf node_exporter-*.tar.gz
sudo cp node_exporter-*/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
# 创建 systemd 服务
sudo tee /etc/systemd/system/node_exporter.service > /dev/null <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
配置 Prometheus
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
方案二:使用 Grafana 可视化流量数据
关键监控指标
在 Grafana 中配置以下面板:
| 指标 | 说明 | 告警阈值 |
|---|---|---|
node_network_receive_bytes_total | 接收流量 | 月累计 > 80% 配额 |
node_network_transmit_bytes_total | 发送流量 | 月累计 > 80% 配额 |
rate(node_network_receive_bytes[5m]) | 实时接收速率 | > 100MB/s |
rate(node_network_transmit_bytes[5m]) | 实时发送速率 | > 100MB/s |
流量趋势面板配置
创建一个展示月度流量趋势的面板,使用 PromQL 查询:
# 本月累计接收流量
increase(node_network_receive_bytes_total{device="eth0"}[30d])
# 本月累计发送流量
increase(node_network_transmit_bytes_total{device="eth0"}[30d])
方案三:Shell 脚本实现简单流量告警
如果不想部署完整的 Prometheus 栈,可以使用简单的 Shell 脚本:
#!/bin/bash
# traffic_alert.sh - 简单流量监控脚本
INTERFACE="eth0"
MONTHLY_QUOTA_GB=1000
ALERT_THRESHOLD=80 # 百分比
# 获取本月已用流量(字节)
USED_BYTES=$(cat /sys/class/net/${INTERFACE}/statistics/rx_bytes)
USED_BYTES=$((USED_BYTES + $(cat /sys/class/net/${INTERFACE}/statistics/tx_bytes)))
# 转换为 GB
USED_GB=$(echo "scale=2; $USED_BYTES / 1073741824" | bc)
# 计算使用率
USAGE_PERCENT=$(echo "scale=2; $USED_GB * 100 / $MONTHLY_QUOTA_GB" | bc)
# 检查是否超过阈值
if (( $(echo "$USAGE_PERCENT > $ALERT_THRESHOLD" | bc -l) )); then
echo "$(date): 警告! ${INTERFACE} 流量使用率 ${USAGE_PERCENT}% (${USED_GB}GB/${MONTHLY_QUOTA_GB}GB)" | \
mail -s "VPS 流量告警" your-email@example.com
fi
将脚本加入 crontab 每小时执行一次:
crontab -e
0 * * * * /path/to/traffic_alert.sh
方案四:使用 Cloudflare CDN 节省出站流量
对于面向公网的网站,Cloudflare CDN 是最有效的省钱方案:
优势
- 缓存静态资源:CSS、JS、图片等由 CDN 边缘节点响应,不消耗源站流量
- 压缩传输:自动 gzip/brotli 压缩减少传输量
- 免费套餐:无限带宽,每日 10 万请求
- DDoS 防护:内置免费防护,避免攻击造成的流量浪费
配置步骤
# 1. 启用 Cloudflare 代理(橙色云朵)
# 2. 开启自动压缩
# Settings -> Optimization -> Compression -> On
# 3. 设置缓存规则
# Cache Rules -> Cache Everything -> TTL: 1 hour
# 4. 开启 Brotli 压缩
# Edge Browser Caching -> True Client IP
方案五:带宽限速与 QoS 配置
使用 tc 限制接口带宽
# 限制 eth0 最大出站带宽为 100Mbps
sudo tc qdisc add dev eth0 root handle 1: htb default 12 rtt 250 mpu 0 \
maxburst 14 avpkt 1000 bandwidth 100mbit ceil 100mbit
# 添加子队列
sudo tc class add dev eth0 parent 1: classid 1:12 htb rate 100mbit ceil 100mbit burst 15k
使用 cgroup 限制 Docker 容器流量
# 创建 cgroup 并限制带宽
sudo cgcreate -g net_cls,net_pids:/docker-limited
sudo cgset -r net_pids.limit=100 docker-limited
流量优化最佳实践
1. 启用 HTTP/2 和 HTTP/3
# nginx.conf
http {
# HTTP/2
listen 443 ssl http2;
# Brotli 压缩
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript;
}
2. 图片优化
# 使用 cwebp 转换 WebP 格式
cwebp -q 80 input.jpg -o output.webp
# 通常可减少 30-50% 文件大小
3. API 响应压缩
location /api/ {
gzip on;
gzip_types application/json text/plain;
gzip_min_length 1000;
}
4. 数据库查询优化
减少不必要的数据库查询可以显著降低应用层流量:
-- 使用 EXPLAIN 分析慢查询
EXPLAIN SELECT * FROM posts WHERE status = 'published';
-- 添加合适的索引
CREATE INDEX idx_posts_status ON posts(status);
月度流量报告自动生成
创建一个脚本来生成月度流量报告:
#!/bin/bash
# monthly_traffic_report.sh
REPORT_DATE=$(date +%Y-%m)
QUOTA_GB=1000
# 统计本月流量
RX_TOTAL=$(awk '/eth0/ {sum += $1} END {print sum}' /proc/net/dev)
TX_TOTAL=$(awk '/eth0/ {sum += $2} END {print sum}' /proc/net/dev)
RX_GB=$(echo "scale=2; $RX_TOTAL / 1073741824" | bc)
TX_GB=$(echo "scale=2; $TX_TOTAL / 1073741824" | bc)
TOTAL_GB=$(echo "scale=2; $RX_GB + $TX_GB" | bc)
USAGE_PCT=$(echo "scale=2; $TOTAL_GB * 100 / $QUOTA_GB" | bc)
# 生成报告
cat <<EOF
========================================
VPS 流量月度报告 - ${REPORT_DATE}
========================================
接收流量: ${RX_GB} GB
发送流量: ${TX_GB} GB
总用量: ${TOTAL_GB} GB
套餐配额: ${QUOTA_GB} GB
使用率: ${USAGE_PCT}%
----------------------------------------
EOF
总结
通过实施上述方案,你可以:
- 实时掌握 VPS 流量使用情况
- 提前预警,避免意外超额费用
- 优化内容分发,减少不必要的流量消耗
- 定期生成报告,持续改进运维策略
记住,预防总是比补救便宜。花少量时间配置监控系统,就能避免每月数百元的超额费用。
