linux内核参数调优是java高并发服务稳定承载万级并发的前提,需在/etc/sysctl.conf中配置6组关键参数:连接队列(somaxconn、tcp_max_syn_backlog)、time_wait复用(tcp_tw_reuse、fin_timeout、ip_local_port_range)、文件描述符(fs.file-max)、tcp缓冲区(rmem/wmem)、内存管理(swappiness、overcommit_memory)及基础防护(syncookies等),并配合ulimit与应用重启生效。

Java 应用本身不直接配置 Linux 内核参数,但部署在 Linux 上的高并发 Java 服务(如 Spring Boot、Netty 网关、Dubbo 服务)对网络连接、文件描述符、内存回收等非常敏感。内核参数没调好,哪怕代码再优,也会卡在 TIME_WAIT 堆积、端口耗尽、连接拒绝、GC 频繁 swap 等底层瓶颈上。真正起作用的是 /etc/sysctl.conf —— 它是 Java 服务稳定承载万级并发的前提。
关键不是“Java 怎么配”,而是“Java 服务需要哪些内核支撑,怎么配才有效”
✅ 高并发 Java 服务最常触发的内核瓶颈
- 新连接被拒绝:
accept queue full(监听队列溢出) - 大量
CLOSE_WAIT/TIME_WAIT:连接释放慢、端口复用难 -
java.net.BindException: Address already in use:临时端口不够用 -
IOException: Too many open files:虽由ulimit控制,但fs.file-max是系统级底限 - GC 时频繁卡顿或 OOM Killer 杀进程:
swappiness过高 + 内存缓冲失控
这些都不是 JVM 参数能解决的,必须靠 sysctl.conf 对齐。
?️ 必配的 6 组参数(专为 Java 服务优化)
所有参数写入
/etc/sysctl.conf(或/etc/sysctl.d/99-java-tuning.conf),执行sudo sysctl --system生效(推荐用--system,兼容/etc/sysctl.d/)
-
连接接入能力(防丢连接)
net.core.somaxconn = 65535 # 全连接队列上限,Tomcat/Nginx 的 `backlog` 不能超它 net.ipv4.tcp_max_syn_backlog = 65535 # 半连接队列,扛住 SYN 洪泛或突发建连 net.core.netdev_max_backlog = 65535 # 网卡收包队列,防突发流量丢包
-
TIME_WAIT 与端口复用(提升连接周转)
net.ipv4.tcp_tw_reuse = 1 # 允许 TIME_WAIT 套接字重用于 *客户端* 新建连接(Java 作为 HTTP 调用方时生效) net.ipv4.tcp_fin_timeout = 30 # 缩短 FIN_WAIT_2 超时,加快进入 TIME_WAIT net.ipv4.ip_local_port_range = 1024 65535 # 扩大临时端口范围,避免 `bind: address already in use`
-
文件描述符支撑(配合 Java 的
ulimit)fs.file-max = 2097152 # 系统级最大文件句柄数(建议 ≥ 2× Java 进程 soft nofile 总和)
⚠️ 同时需在
/etc/security/limits.conf中设:* soft nofile 1048576 * hard nofile 1048576
-
TCP 缓冲区(适配高吞吐 API 或长连接场景)
net.core.rmem_max = 16777216 # 接收缓冲上限(16MB) net.core.wmem_max = 16777216 # 发送缓冲上限 net.ipv4.tcp_rmem = 4096 262144 16777216 # min/default/max,让内核自动调优 net.ipv4.tcp_wmem = 4096 262144 16777216
-
内存管理(防止 Java 进程被 OOM Kill)
vm.swappiness = 10 # 降低 swap 倾向;数据库类 Java 服务可设为 1 vm.overcommit_memory = 2 # 严格内存分配,避免虚假承诺导致 OOM vm.vfs_cache_pressure = 150 # 加速 inode/dentry 回收(适合大量小文件读取的微服务)
-
基础防护(生产环境必须开)
net.ipv4.tcp_syncookies = 1 # 抵御轻量 SYN Flood(不影响性能) kernel.randomize_va_space = 2 # 开启完整 ASLR,增强 JVM 堆漏洞防护 kernel.sysrq = 0 # 关闭 SysRq(除非远程调试强需求)
? 验证是否真生效(别只信 sysctl -p 输出)
- 查运行值:
sysctl net.core.somaxconn net.ipv4.tcp_tw_reuse fs.file-max
- 查 Java 进程实际可用端口范围:
cat /proc/sys/net/ipv4/ip_local_port_range
- 观察当前 TIME_WAIT 连接数:
ss -s | grep -i "timewait"
- 检查 socket 缓冲是否按预期加载(某连接):
ss -i sport = :8080 | head -2 # 看 rcv_space/snd_space 字段
⚠️ 注意事项(Java 场景特别容易踩坑)
-
tcp_tw_reuse只对 主动发起连接的客户端 有效(如 Feign、RestTemplate、OkHttp 调用下游),服务端监听不受影响 -
tcp_tw_recycle已从 Linux 4.12+ 移除,且 NAT 下会出错,绝对不要配 -
vm.swappiness = 0在 Kubernetes 节点常见,但普通 Java 服务设为 0 可能导致内存紧张时直接 OOM,10 更稳妥 - 所有
net.*参数修改后,必须重启 Java 应用才能使用新连接队列/端口范围(旧连接仍沿用旧内核状态) - 若用 Docker/K8s,宿主机
sysctl.conf仍生效,但容器内需加--sysctl参数或 privileged 才能覆盖(谨慎)
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











