Linux高并发内核优化

一、用户级/系统最大文件句柄

文件句柄(File Handle):是 Linux 内核为进程打开的每个对象(文件、设备、socket 等)分配的唯一标识符(ID 编号)。它充当进程与内核之间的桥梁,用于内核快速寻址、进程间通信以及资源管理,是提升 Linux 系统 I/O 处理效率的关键机制。系统默认的 1024 限制在高并发场景下会出现 "Too many open files" 错误,导致即使系统内存资源充足,业务系统也会因无法建立新连接或打开必要文件而陷入卡死、拒绝服务的状态。

1、 默认限制与高并发瓶颈

Linux 系统为每个用户进程和整个系统都设置了文件句柄数量的上限。

  • 用户级限制(ulimit -n):默认通常为 1024。这限制了单个进程能同时打开的文件描述符数量。
  • 系统级限制(fs.file-max):定义了整个操作系统所有进程可打开的文件句柄总数。

在高并发场景(如 Web 服务器、数据库、消息中间件)中,一个进程可能需要同时处理成千上万的网络连接(每个连接至少占用一个文件句柄)。默认的 1024 限制会迅速被耗尽,导致进程抛出 "Too many open files" 错误。此时,即使服务器拥有充足的内存和 CPU 资源,业务系统也会因无法建立新连接或打开必要文件而陷入卡死、拒绝服务的状态。

2、用户级/系统级优化

2.1、用户级优化

(1)修改 /etc/security/limits.conf/etc/security/limits.d/*.conf 文件。

(2)修改内容如下:

bash 复制代码
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
root soft nofile 65535
root hard nofile 65535

# 重新登录后执行
ulimit -n
# 应显示 65535

注:* 代表所有普通用户,nofile 是最大文件句柄数,nproc 为最大进程数,softhard 代表软硬限制,数值代表设置值。

在终端输入 ulimit -n 查看软限制(当前生效值),输入 ulimit -Hn 查看硬限制(最大值上限)。

2.2、系统级优化

(1)查看当前值:

bash 复制代码
sysctl fs.file-max
cat /proc/sys/fs/file-max

(2)修改内容如下:

bash 复制代码
fs.file-max = 655350 # 系统最大打开文件数,这个数应为单进程的2倍及以上,建议采用10倍。
kernel.pid_max = 65535 # 表示本机可以运行多少个进程,系统默认是32768,偏少。
fs.inotify.max_user_instances = 8192 # 单用户可创建 inotify 监控实例数
fs.inotify.max_user_watches = 524288 # 用户可以同时监控的文件数
sysctl -p # 生效配置

3、systemd 服务优化

关键点/etc/security/limits.conf 对 systemd 管理的服务不生效。

为特定服务设置(以 nginx 为例):

bash 复制代码
# 创建服务配置覆盖目录
sudo mkdir -p /etc/systemd/system/nginx.service.d

# 创建配置文件
sudo vim /etc/systemd/system/nginx.service.d/limits.conf

# 添加以下内容
[Service]
LimitNOFILE=65535

# 重载并重启服务
sudo systemctl daemon-reload
sudo systemctl restart nginx

# 验证
cat /proc/$(pidof nginx | awk '{print $1}')/limits | grep "open files"

常见应用场景的推荐配置:

应用类型 建议 nofile 值 说明
Nginx(高并发) 100000 - 200000 处理大量静态文件/反向代理
MySQL/PostgreSQL 20000 - 50000 数据库连接数相关
Java 应用(Tomcat) 65535 - 100000 根据线程数调整
Redis 10000 - 20000 主要受连接数影响
Docker 容器 1048576 容器内应用需要更大值

二、 网络高并发内核优化

网络传输层主要是 TCP、UDP 两种协议栈,现网 80% 业务采用 TCP。本文针对 TCP 进行内核优化。

(1)编辑 /etc/sysctl.conf 文件。

(2)填写如下内容到文件里面:

bash 复制代码
net.ipv4.ip_local_port_range = 1024 65535 # 设置端口的可用范围
net.ipv4.tcp_tw_reuse = 1 # 允许新连接复用 TIME_WAIT 端口,避免出现端口耗尽问题
net.ipv4.tcp_tw_recycle = 0 # 关闭 TIME_WAIT 快速回收
net.ipv4.tcp_max_tw_buckets = 50000 # 防止 TIME_WAIT 占满服务器端口和内存
net.ipv4.tcp_syncookies = 1 # 开启防护 SYN 缓存防攻击
net.ipv4.ip_forward = 1 # 开启路由转发,在 Docker 场景、NAT 场景使用

三、内存内核优化

为了防止 OOM、脏页问题,需要对内存内核进行优化,提升内核响应速度。

(1)编辑 /etc/sysctl.conf 文件。

(2)填写如下内容到文件里面:

bash 复制代码
vm.swappiness = 10  # 设置 SWAP 交换分区倾向,范围 0-100,本文设置为 10,尽量不使用交换内存。
vm.dirty_ratio = 20  # 数据写入内存,但是还没刷到硬盘。在脏页达到总内存 20% 时会强制刷入硬盘。
vm.dirty_background_ratio = 10  # 脏页达到总内存 10% 时主动刷入硬盘,不阻塞业务。
vm.dirty_expire_centisecs = 3000 # 脏页在内存中超过 30 秒进行落盘。
vm.dirty_writeback_centisecs = 500 # 每隔 5 秒进行脏页查询。
vm.overcommit_memory = 1 # 允许内存超分,数据库、Redis 场景应用,避免服务启动失败。
vm.overcommit_ratio = 80 # 物理内存给内核预留 20%,应用可用 80%。
vm.nr_hugepages = 2 # 设置大页内存,固定内存不被置换。数值以内存数据为准。

四、内核安全防控

提升内核层面安全,需要防范各类安全风险。最近的 Dirty Pipe 漏洞、copy_from_user 漏洞都可通过提权获取 root 权限。

(1)编辑 /etc/sysctl.conf 文件。

(2)填写如下内容到文件里面:

bash 复制代码
kernel.kptr_restrict = 2 # 禁止内核暴露内存地址,防止提权利用。
# 禁止接收 ICMP 重定向报文,防止路由篡改
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# 忽略广播 ARP、禁止 ARP 欺骗
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.icmp_echo_ignore_broadcasts = 1 # 禁止响应广播 ping,防止内网扫描、DDoS 放大攻击。
net.ipv4.icmp_ignore_bogus_error_responses = 1  # 忽略错误 ICMP 报文,防畸形包攻击。
相关推荐
perfect123126451 小时前
轻量运维工具fastdp v6版本
linux·运维
linksinke1 小时前
在 CentOS 7.x 外网环境离线构建便携式 Python 3.11.4 的方案参考
linux·python·centos
xuefuhe1 小时前
Linux:/bin/false 与 nologin 的本质区别与安全防范
linux
2401_868534781 小时前
RTOS与Linux的区别对比解析
linux·运维·服务器
Bert.Cai1 小时前
Linux chmod命令详解
linux·运维·服务器
eggrall1 小时前
Linux信号——信号捕捉
linux·运维·服务器
.千余1 小时前
【Linux】 TCP进阶详解:字节流、粘包问题、异常情况与UDP完整对比2
linux·运维·c语言·开发语言·经验分享·笔记·php
PascalMing1 小时前
从零实现一款 Windows 下的 SSH 批量运维工具:LinuxSshTools 技术详解
运维·windows·ssh
Bert.Cai2 小时前
Linux chown命令详解
linux·运维·服务器