如何轻松管理Ubuntu ulimit网络带宽限制以优化系统性能?
- 内容介绍
- 文章标签
- 相关推荐
再看常见痛点,为什么我的 Ubuntu 网络经常卡顿?
很多程序管理员和开发者在部署 Web 服务、数据库或容器化应用时都会遇到以下困扰:
- 并发连接数突然上限导致新请求被拒绝或超时。
- 网络吞吐量不达标即使服务器硬件充足,也出现明显的带宽瓶颈。
- CPU/内存使用看似正常,却在高并发时崩溃。
- 程序重启后所有调优设置失效每次都要手动重新配置。
这些问题往往源于默认的资源限制过低,还有缺乏对网络流量的细粒度控制。下面提供一套完整、可复制的方法,让你轻松管理 Ubuntu 的资源限制并间接提高带宽利用率。
一、认识 ulimit它能干什么不能干什么?
ulimit 是 Bash提供的内建命令,用于查看或设置当前使用者会话的资源软/硬限制。常见的限制项包括:
- 文件描述符决定单个进程能够打开多少个文件或套接字。老实说,
- 进程数同一使用者可同时运行的最大进程数。
- 主要文件大小、堆栈大小等其它资源
注意:ulimit 本身并不直接控制带宽,它只能通过提高相关资源为网络应用提供更大的“入口”。真正的带宽限制需要配合 Linux 的流量控制工具(tc/wondershaper/Cgroups v2 net_cls) 实现。
二、先把 “打开文件描述符” 这块卡住的瓶颈解决掉
1. 查看当前限制
# 查看软限制
ulimit -Sn
# 查看硬限制
ulimit -Hn
# 一键显示全部
ulimit -a
2. 临时提高
# 将软限制提高到 65535
ulimit -Sn 65535
# 同时提高硬限制
ulimit -Hn 65535
3. 永久生效:修改设置文件
a. /etc/security/limits.conf
# 示例:对所有使用者或特定使用者提高软/硬限制
* soft nofile 65535
* hard nofile 65535
# 若只想针对 www-data:
www-data soft nofile 65535
www-data hard nofile 65535
b. /etc/pam.d/common-session*
# 在 common-session 和 common-session-noninteractive 中加入:
session required pam_limits.so
d. systemd 服务层面的配置
# 创建 /etc/systemd/system/myservice.service.d/override.conf
LimitNOFILE=65535
# 重载并重新启动
systemctl daemon-reload
systemctl restart myservice.service
三、使用 tc 对带宽进行精准控制
1. 安装必备工具
# iproute2 包已经包含 tc,大多数 Ubuntu 默认已装;若缺失:
sudo apt-get update && sudo apt-get install iproute2
2. 基本概念快速回顾
- Tc 类别 : 定义带宽上限/下限。
- Tc 队列规则 : 在接口根部挂载,用来组织 class。
- Tc 过滤器 : 将特定流量导入对应 class。话说回来,
3. 示例:为 eth0 接口设定上传/下载上限为 100 Mbps
# 清除已有规则
sudo tc qdisc del dev eth0 root
sudo tc qdisc add dev eth0 root handle 1: htb default 30
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \ match ip dport 80 0xffff flowid 1:10
tc -s qdisc show dev eth0 tc -s class show dev eth0
4. 按使用者 UID 限制带宽
# 标记属于特定 UID 的出站流量。例如 uid=1001:
sudo iptables -t mangle -A OUTPUT -m owner --uid-owner 1001 -j MARK --set-mark 10
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 handle 10 fw flowid 1:20
四、使用 Cgroup v2 的 net_cls 控制器实现更细粒度管理
Cgroup 可以把 CPU、内存、I/O 与网络划分到独立组,实现“一键式”资源配额。下面演示如何给某个程序服务分配专属带宽:
a. 启用 net_cls 控制器
# 检查是否已挂载 cgroup v2:
mount | grep cgroup2
sudo mount -t cgroup2 none /sys/fs/cgroup
echo +netcls | sudo tee /sys/fs/cgroup/cgroup.subtreecontrol
b. 创建 cgroup 并绑定进程
# 创建名为 myapp 的组:
sudo mkdir /sys/fs/cgroup/myapp
printf "0x00110011" | sudo tee /sys/fs/cgroup/myapp/net_cls.classid
echo 1234 | sudo tee /sys/fs/cgroup/myapp/cgroup.procs
b. 在 TC 中匹配该类 ID
sudo tc filter add dev eth0 protocol ip parent 1: prio 10 handle \ ffff flowid 1:11 \ fw flowid ffff # 注意这里使用 fw 来匹配 net_cls 标记。
Cgroup+TC 的组合非常适合容器网站、K8s 节点还有多租户 VPS 环境。其实,
五、让设置持久化:开机自动加载方案
a. 使用 Systemd 单元文件统一管理 TC 配置
# 创建 /etc/systemd/system/tc-bandwidth.service
Description=Configure traffic control limits on boot
After=network.target
Type=oneshot ExecStart=/usr/local/sbin/tc-setup.sh RemainAfterExit=yes
WantedBy=multi-user.target
bash
set -e
DEV="eth0"
tc qdisc del dev $DEV root || true
tc class add dev $DEV parent 1: classid 1:ff htb rate ${TOTAL_RATE:-"500mbit"}
if ];n tc class add dev $DEV parent ... fi
exit 0
bash
chmod +x /usr/local/sbin/tc-setup.sh
systemctl daemon-reload
systemctl enable --now tc-bandwidth.service
b. 把 ulimit 持久化写入全局 profile
# 编辑 /etc/profile.d/99-ulimit.sh
ulimit -n ${ULIMITNOFILE:-65535}
ulimit -u ${ULIMITNPROC:-4096}
bash
chmod +x /etc/profile.d/99-ulimit.sh
source /etc/profile.d/99-ulimit.sh # 手动加载测试
六、监控与验证:确保调优真的生效
| 监控工具 & 场景 | 关键指标 |
|---|---|
| Bash 内置检查 | ulimit -a 显示当前软硬限制 |
ss -s 或 netstat -s TCP sockets 数量是否已突破旧阈值 |
*如果发现大量 drops,则说明 TC 限速过低,需要适当调高;若仍然出现 “Too many open files” 错误,则继续提高 `/etc/security/limits.conf` 中的 `nofile` 值。*
七、常用方法清单
- • **先排查**:使用 `dmesg | grep –i limit` 或 `journalctl -k` 确认是否因资源受限导致异常。
- • **统一入口**:把所有 ulimit 设置放在 `/etc/security/limits.conf` + `/etc/profile.d/*.sh`,避免散落在不同使用者的 `.bashrc` 中。
- • **分层管控**:Cgroup 用于全局或容器级别控制;TC 用于接口或端口级别细粒度控制;两者结合最灵活,
- • **保持可审计**:将所有 TC 命令写入脚本并纳入 systemd 管理,这样每次重启都有日志记录。
- • **监控告警**:结合 Promeus node_exporter + blackbox_exporter。将 `tc -s` 与 `ulimit` 状态暴露为指标,一旦超过阈值即时报警。
- • **渐进式调优**:从提高文件描述符开始 → 添加基本 TC 限速 → 引入 Cgroup → 最终调到极限,以免引发不可预料的问题。老实说,
- • **文档化**:在团队 wiki 中记录每台机器的 “resource‑limit baseline”。方便新成员快速定位问题根源。
通过上述步骤。你可以从根本上消除 “打开文件太多导致连接被拒”、 “高并发时带宽被抢占”、还有 “重启后配置失效” 三大痛点,让 Ubuntu 程序在 高负载场景下保持稳定、高效运行。
再看常见痛点,为什么我的 Ubuntu 网络经常卡顿?
很多程序管理员和开发者在部署 Web 服务、数据库或容器化应用时都会遇到以下困扰:
- 并发连接数突然上限导致新请求被拒绝或超时。
- 网络吞吐量不达标即使服务器硬件充足,也出现明显的带宽瓶颈。
- CPU/内存使用看似正常,却在高并发时崩溃。
- 程序重启后所有调优设置失效每次都要手动重新配置。
这些问题往往源于默认的资源限制过低,还有缺乏对网络流量的细粒度控制。下面提供一套完整、可复制的方法,让你轻松管理 Ubuntu 的资源限制并间接提高带宽利用率。
一、认识 ulimit它能干什么不能干什么?
ulimit 是 Bash提供的内建命令,用于查看或设置当前使用者会话的资源软/硬限制。常见的限制项包括:
- 文件描述符决定单个进程能够打开多少个文件或套接字。老实说,
- 进程数同一使用者可同时运行的最大进程数。
- 主要文件大小、堆栈大小等其它资源
注意:ulimit 本身并不直接控制带宽,它只能通过提高相关资源为网络应用提供更大的“入口”。真正的带宽限制需要配合 Linux 的流量控制工具(tc/wondershaper/Cgroups v2 net_cls) 实现。
二、先把 “打开文件描述符” 这块卡住的瓶颈解决掉
1. 查看当前限制
# 查看软限制
ulimit -Sn
# 查看硬限制
ulimit -Hn
# 一键显示全部
ulimit -a
2. 临时提高
# 将软限制提高到 65535
ulimit -Sn 65535
# 同时提高硬限制
ulimit -Hn 65535
3. 永久生效:修改设置文件
a. /etc/security/limits.conf
# 示例:对所有使用者或特定使用者提高软/硬限制
* soft nofile 65535
* hard nofile 65535
# 若只想针对 www-data:
www-data soft nofile 65535
www-data hard nofile 65535
b. /etc/pam.d/common-session*
# 在 common-session 和 common-session-noninteractive 中加入:
session required pam_limits.so
d. systemd 服务层面的配置
# 创建 /etc/systemd/system/myservice.service.d/override.conf
LimitNOFILE=65535
# 重载并重新启动
systemctl daemon-reload
systemctl restart myservice.service
三、使用 tc 对带宽进行精准控制
1. 安装必备工具
# iproute2 包已经包含 tc,大多数 Ubuntu 默认已装;若缺失:
sudo apt-get update && sudo apt-get install iproute2
2. 基本概念快速回顾
- Tc 类别 : 定义带宽上限/下限。
- Tc 队列规则 : 在接口根部挂载,用来组织 class。
- Tc 过滤器 : 将特定流量导入对应 class。话说回来,
3. 示例:为 eth0 接口设定上传/下载上限为 100 Mbps
# 清除已有规则
sudo tc qdisc del dev eth0 root
sudo tc qdisc add dev eth0 root handle 1: htb default 30
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \ match ip dport 80 0xffff flowid 1:10
tc -s qdisc show dev eth0 tc -s class show dev eth0
4. 按使用者 UID 限制带宽
# 标记属于特定 UID 的出站流量。例如 uid=1001:
sudo iptables -t mangle -A OUTPUT -m owner --uid-owner 1001 -j MARK --set-mark 10
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 handle 10 fw flowid 1:20
四、使用 Cgroup v2 的 net_cls 控制器实现更细粒度管理
Cgroup 可以把 CPU、内存、I/O 与网络划分到独立组,实现“一键式”资源配额。下面演示如何给某个程序服务分配专属带宽:
a. 启用 net_cls 控制器
# 检查是否已挂载 cgroup v2:
mount | grep cgroup2
sudo mount -t cgroup2 none /sys/fs/cgroup
echo +netcls | sudo tee /sys/fs/cgroup/cgroup.subtreecontrol
b. 创建 cgroup 并绑定进程
# 创建名为 myapp 的组:
sudo mkdir /sys/fs/cgroup/myapp
printf "0x00110011" | sudo tee /sys/fs/cgroup/myapp/net_cls.classid
echo 1234 | sudo tee /sys/fs/cgroup/myapp/cgroup.procs
b. 在 TC 中匹配该类 ID
sudo tc filter add dev eth0 protocol ip parent 1: prio 10 handle \ ffff flowid 1:11 \ fw flowid ffff # 注意这里使用 fw 来匹配 net_cls 标记。
Cgroup+TC 的组合非常适合容器网站、K8s 节点还有多租户 VPS 环境。其实,
五、让设置持久化:开机自动加载方案
a. 使用 Systemd 单元文件统一管理 TC 配置
# 创建 /etc/systemd/system/tc-bandwidth.service
Description=Configure traffic control limits on boot
After=network.target
Type=oneshot ExecStart=/usr/local/sbin/tc-setup.sh RemainAfterExit=yes
WantedBy=multi-user.target
bash
set -e
DEV="eth0"
tc qdisc del dev $DEV root || true
tc class add dev $DEV parent 1: classid 1:ff htb rate ${TOTAL_RATE:-"500mbit"}
if ];n tc class add dev $DEV parent ... fi
exit 0
bash
chmod +x /usr/local/sbin/tc-setup.sh
systemctl daemon-reload
systemctl enable --now tc-bandwidth.service
b. 把 ulimit 持久化写入全局 profile
# 编辑 /etc/profile.d/99-ulimit.sh
ulimit -n ${ULIMITNOFILE:-65535}
ulimit -u ${ULIMITNPROC:-4096}
bash
chmod +x /etc/profile.d/99-ulimit.sh
source /etc/profile.d/99-ulimit.sh # 手动加载测试
六、监控与验证:确保调优真的生效
| 监控工具 & 场景 | 关键指标 |
|---|---|
| Bash 内置检查 | ulimit -a 显示当前软硬限制 |
ss -s 或 netstat -s TCP sockets 数量是否已突破旧阈值 |
*如果发现大量 drops,则说明 TC 限速过低,需要适当调高;若仍然出现 “Too many open files” 错误,则继续提高 `/etc/security/limits.conf` 中的 `nofile` 值。*
七、常用方法清单
- • **先排查**:使用 `dmesg | grep –i limit` 或 `journalctl -k` 确认是否因资源受限导致异常。
- • **统一入口**:把所有 ulimit 设置放在 `/etc/security/limits.conf` + `/etc/profile.d/*.sh`,避免散落在不同使用者的 `.bashrc` 中。
- • **分层管控**:Cgroup 用于全局或容器级别控制;TC 用于接口或端口级别细粒度控制;两者结合最灵活,
- • **保持可审计**:将所有 TC 命令写入脚本并纳入 systemd 管理,这样每次重启都有日志记录。
- • **监控告警**:结合 Promeus node_exporter + blackbox_exporter。将 `tc -s` 与 `ulimit` 状态暴露为指标,一旦超过阈值即时报警。
- • **渐进式调优**:从提高文件描述符开始 → 添加基本 TC 限速 → 引入 Cgroup → 最终调到极限,以免引发不可预料的问题。老实说,
- • **文档化**:在团队 wiki 中记录每台机器的 “resource‑limit baseline”。方便新成员快速定位问题根源。
通过上述步骤。你可以从根本上消除 “打开文件太多导致连接被拒”、 “高并发时带宽被抢占”、还有 “重启后配置失效” 三大痛点,让 Ubuntu 程序在 高负载场景下保持稳定、高效运行。

