节前发现 VPS 上运行节点,流量忽然增加,紧急增加了限速。整理下如何用 Linux
tc做限速、如何做月流量守护、如何通过 Telegram 实时接收告警。
一、问题背景
跑节点常见两个冲突目标:
- 节点要尽量稳定在线(避免频繁超时、掉线)。
- VPS 月流量有限(例如 1TB),不能无限跑。
之前运行正常而且节点流量不是很高,忽然流量突增,右节点 2 天跑了 700G,于是赶紧使用 claude code(后被封了 :()、gemini 生成脚本。
主要目标是能够限制指定端口的流量,但是也不能影响 ssh 等服务以免影响正常服务,涉及的命令也梳理了一下。
二、tc 是什么及主要参数
tc(traffic control)是 Linux 内核流量控制工具,主要参数:
- qdisc: 调度排队
- class: 流量分类
- filter: 过滤器分类
- action: 动作,drop/mirred
- handle: 对象的标识
- chain: 过滤器链,用于 tc filter,大配量优化用
- monitor: 监控
三、tc 核心概念
1. qdisc(队列规则)
qdisc 是调度入口
| 工具名称 | 核心定位 | 核心特性 & 避坑指南 | 典型实战场景 |
|---|---|---|---|
| fq_codel | 公平+低延迟 (Scheduling) | ✅ 现代标准。结合了多流公平(FQ)与主动弃包(CoDel)。 💡 抗 Bufferbloat 神器。 | 通用默认防卡顿 (HTB 的最佳叶子节点) |
| Cake | 全能流控 (Shaping+AQM) | ✅ fq_codel 的进化版,自带整形功能。⚠️ 对内核版本要求较高 (OpenWrt 常用)。 | 软路由/家庭宽带 (一步到位的低延迟) |
| TBF | 简单限速 (Shaping) | ✅ 令牌桶算法,配置简单。 ⚠️ 一刀切,不分流,参数不当会导致吞吐抖动。 | 网卡暴力限速 (如限制 eth0 总速 10M) |
| SFQ | 老牌公平 (Scheduling) | ⚠️ 仅保证连接间的公平,不负责压低延迟。 💡 防止单连接霸占带宽。 | 简单的多用户共享 |
| pfifo_fast | 旧默认 (Scheduling) | 🛑 只有简单的 3 个优先级。 ⚠️ 不抗 Bufferbloat,P2P 一多 SSH 必卡。 | 老旧系统默认 (建议替换) |
| Netem | 网络仿真 (Utility) | ✅ 模拟延时、丢包、乱序、重复。 💡 开发测试专用。 | 弱网环境测试 (测试程序健壮性) |
| Ingress | 入站控制 (Utility) | ⚠️ 入方向通常只能丢包(Policing)。 💡 若要整形需配合 IFB 设备。 | 限制下载速度 (配合 IFB) |
tbf(Token Bucket Filter)由于其不区分流量类型,当 P2P 数据量增大拥堵时,ssh 请求包需要进行排队导致出现 head-of-line blocking,致使 ssh 延迟极高甚至无法登录。
后来选用了 htb(Hierarchical Token Bucket),它可以通过 class 对流量分类,对于节点流量和 ssh 流量进行区分,进行分类后,再通过 fq_codel,根据限流的需求进行精细化配置。
2. class(分类)
| 参数 | 全称 | 技术定义 (Definition) | 最佳实践策略 (Best Practice) |
|---|---|---|---|
| rate | Guaranteed Rate (保障速率) | 该 Class 承诺的最低可用带宽。即使网络拥堵,HTB 也会确保该类流量能获得此速率。 | SSH/交互类:设为 512Kbps - 2Mbps(确保连接存活)。 业务类:设为剩余带宽的预估值。 |
| ceil | Ceiling Rate (上限速率) | 该 Class 允许借用带宽后的最大速率。仅当父类有空闲带宽时,速率可从 rate 提升至 ceil。 | 硬限速:设为 ceil = rate。弹性共享:设为物理带宽上限(允许借用空闲资源)。 |
| burst | Burst (令牌桶容量) | 允许在短时间内突破 rate 限制的数据量(字节)。决定了速率的平滑程度。 | 交互类:适当调大(如 20KB-50KB),允许瞬间响应。 大流量:默认即可,过大会导致流量整形失效。 |
| cburst | Ceiling Burst (上限桶容量) | 允许在短时间内突破 ceil 限制的数据量。主要受网卡物理特性限制。 | 通常保持默认。如果发现无法达到千兆线速,可适当调大。 |
| prio | Priority (优先级) | 争抢空闲带宽(Ceil - Rate)时的优先权。数值越小,优先级越高(0-7)。 | SSH/DNS:设为 0 或 1(最高)。 P2P/下载:设为 5 或更低(避免抢占关键流量)。 |
| quantum | Quantum (配额) | 在 DRR 调度算法中,每一轮服务允许发送的字节数。 | 一般勿动。HTB 会根据 rate 自动计算。手动调整仅用于解决极低速率下的精度问题。 |
| r2q | Rate to Quantum (转换系数) | 全局参数(Root)。用于根据 rate 自动计算 quantum 的系数(Quantum = Rate / r2q)。 | 默认 10。只有在系统日志出现 “quantum is too small” 警告时才需修改。 |
| default | Default Class (默认分类) | 全局参数(Root)。未匹配任何 Filter 规则的流量将进入此 Class。 | 必须配置。建议指向低优先级的 Class(如 1:10),防止未分类的大流量挤死 SSH。 |
用 htb 时将流量划分为不同Class, 用于满足Qos需求
针对 SSH / DNS 这些高交互性协议, 为保证其低延时,需提供高优先级的Qos保障,防止维护期间出现卡顿。
对于业务流量及其他流量放到默认class对其进行流量限制, 防止其占满带宽导致拥堵。
3. filter(过滤规则)
| 选型/参数 | 全称 | 技术定义 | 实战建议与避坑 |
|---|---|---|---|
| u32 | Universal 32-bit Filter | 位匹配过滤器 | 强烈推荐。独立于防火墙运行,实现流量控制与安全策略完全解耦。 |
| fw | Firewall Mark Filter | 标记匹配过滤器 | 复杂场景选型。依赖 iptables 打标,需处理防火墙规则持久化问题。 |
| prio / pref | Priority / Preference | 过滤器的检测顺序 | 管理先行。将 SSH/ICMP 设为 1,业务大流量设为 10 以上。 |
| protocol | Protocol Identifier | 指定链路层协议类型 | 务必显式指定 protocol ip,防止过滤器挂载失败。 |
| match | Match Condition | 具体的匹配表达式 | 下行限速关键。IFB 模式下通常匹配 sport (源端口)。 |
| flowid | Flow Identifier | 命中规则后的分类目标 | 必须与 classid 精确对应,否则流量会进入默认队列。 |
| mirred | Mirror/Redirect Action | 流量镜像/重定向动作 | 下行限流核心。用于将 ingress 流量导向 ifb 设备。 |
| 0xffff | Hex Mask | 十六进制掩码 | 匹配端口时务必带上,防止匹配范围过大误伤其他业务。 |
Filter 过滤器选型,配置过程中使用过 fw(mark) 模式,但该方案与 ufw/firewalld 存在持久化问题和冲突处理问题,处理相对复杂,最终使用 u32 通过端口协议类型完成流量区分,不再依赖防火墙标识区分。
使用 htb 模式,带宽分配依赖以下两个参数:
- rate: 保底额度,这是分配该类别的基础保障带宽。即使系统极其拥堵时也会保证这部分流量分配,设置合理值是保证其不掉线关键。
- ceil: 封顶额度,由于
htb存在借用机制(Borrowing),在带宽空闲情况下,该类型可以申请系统剩余资源来提升速率,但是最终速率受到ceil的限制。
4. 配置示例
| |
graph TD
classDef flow fill:#e1f5fe,stroke:#01579b
classDef limit fill:#ffebee,stroke:#c62828
A[🌊 实时流量输入] --> B{是否超过 rate?}
B -- 否 --> C[✅ 保证通道: 直接发送]:::flow
B -- 是 --> D{是否有闲置带宽?}
D -- 无 --> E[⏳ 降速排队/丢包]:::limit
D -- 有 --> F{是否达到 ceil?}
F -- 否 --> G[🚀 借用模式: 加速发送]:::flow
F -- 是 --> E
四、下行限速(IFB)说明
Linux 原生只方便整形 egress(上行)。下行要用 IFB:
- 把网卡 ingress 重定向到
ifb0 - 在
ifb0上再做htb分类
这个方案可行,但更容易误伤稳定性。如果跑其他业务涉及端口需要进行区分,否则会被业务流量占满带宽后造成丢包。
| |
五、常用 tc 命令速查
1. 查看规则
| |
2. 查看统计(是否真的在限速)
| |
看这几个字段:
Sent:发送字节overlimits:超限被整形次数dropped:丢包backlog/ldelay:排队与延迟
3. 清理规则(紧急恢复)
| |
八、流量监控
目标:在达到月度阈值时自动停容器,避免超额。
1. 工作原理
- 读取网卡累计字节:
/sys/class/net/<iface>/statistics/rx_bytes/sys/class/net/<iface>/statistics/tx_bytes
- 以“基线值”计算本周期增量
- 增量超限后执行:
docker stop <container> - 记录日志并发 Telegram 告警
九、Telegram 机器人注册与告警配置
1. 创建机器人
- 在 Telegram 搜索
@BotFather - 发送
/newbot - 按提示设置机器人名称和用户名
- BotFather 返回
BOT_TOKEN
BOT_TOKEN 形如:
| |
2. 获取 Chat ID
- 在 Telegram 搜索
@IDBot - 发送
/start - 返回的 Id 就是你的
TELEGRAM_CHAT_ID
3. 填入脚本
| |
4. 发送测试消息
| |
十、其他
编写脚本后,防止重启后失效,可以配置 systemd 默认开机运行。
最后更新: 2026-02-18