Linux作为服务器针对使用场景, 有许多需要调优的地方, 本文记录常用优化项.
核心参数调优
通常涉及到/etc/sysctl.conf和/etc/security/limits.conf配置文件的修改.
也可使用命令修改,使用sysctl -p 以立即生效(不必重启).
内核参数设置
sysctl命令可以用来实时的读取/修改内核参数
# 显示所有可用内核参数
sysctl -a
# 加载/etc/sysctl.conf的参数
sysctl -p
提高文件描述符限制
默认的1024偏小.
常用的命令:
# 查看系统当前设置
ulimit -n
# 查看当前进程的限制
cat /proc/$(pgrep java)/limits
# 查看当前进程句柄数
lsof -p $(pgrep java)|wc -l
## 或者使用
ls /proc/$(pgrep java)/fd|wc -l
soft limit类似于warning, hard limit是真实的最大值限制.
有两种方式修改:
临时设置
# 临时增加,重启后失效
ulimit -n 65535
# 单个进程的限制为soft limit
# hard limit应小于当前系统打开的文件描述符
CentOS7设置
在CentOS7使用SystemD启动的服务不同于CentOS6, 对/etc/security/limits.conf的设置不会生效.
需要修改/etc/systemd/system.conf或/etc/systemd/system.conf.d/tomcat.conf,之后重启机器生效.
# 对应下面几项
DefaultLimitCORE=infinity
DefaultLimitNOFILE=102400
DefaultLimitNPROC=102400
CentOS6设置
修改 /etc/security/limits.conf,重启以生效.
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
# 系统级内核句柄限制
fs.file-max = 1000000
其他设置及命令
# 相应增加nr_open
echo 2000000 > /proc/sys/fs/nr_open
# 系统级限制, 上限为nr_open
echo 1000000 > /proc/sys/fs/file-max
# 列出打开/占用的文件描述符
cat /proc/sys/fs/file-nr
# 三个值分别代表 占用/未使用/最大可用值
# 注: lsof只会列出进程占用
lsof | wc -l
# 要得到线程占用,需要使用
ps -eLf
增加可用端口数
默认28000, net.ipv4.ip_local_port_range
- 如果Nginx作代理,需要增加端口范围,否则会出现错误: Cannot assign requested address .
- 如果是压测工具端,报错:connect: cannot assign requested address
IPv4端口可用数:端口号是16位无符号整数,即65535
# 实时生效
echo 12000 64000 > /proc/sys/net/ipv4/ip_local_port_range
# 永久生效
sysctl -w net.ipv4.ip_local_port_range="12000 64000"
可选:最大线程数
一般不需要设置
# 默认31299
echo 100000 > /proc/sys/kernel/threads-max
查看当前线程数:
- top, then hit H to view threads
- top -H
- htop
内存调优
实际上不需要调优.
free -m
# cache和buffers被包含在used,但是当新进程需要而没有free内存时,kernel会回收(写到硬盘)以释放
网络调优
通用网络参数
/etc/sysctl.conf
# 系统网络设置
# 生效值取系统和下面TCP设置值的最大值
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
TCP/IP调优
Backlog Queue
最大连接数队列. 可选, 查看kernel日志决定是否需要调整
net.core.somaxconn
net.core.netdev_max_backlog = 300000
网络缓冲区大小
# TCP读取缓冲区
# 格式: 最小值/默认值/最大值 字节数
# cat /proc/sys/net/ipv4/tcp_rmem
net.ipv4.tcp_rmem = 4096 87380 16777216
# 发送缓冲区
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP内存, 对应 low/pressure/high 页大小(4K)
net.ipv4.tcp_mem = 786432 2097152 3145728
UDP调优
默认比较受限
#改成8M
sysctl -w net.core.rmem_max=8388608
主要参数
Receive-Side Scaling (RSS)
即multi-queue receive, 在基于硬件的多个接受队列间分发网络接受的数据,可以被多核CPU处理以提高性能.
cat /sys/class/net/eth1/queues/<rx-0>/
ethtool --show-rxfh-indir eth1
CLOSE_WAIT 和 TIME_WAIT 解释
- CLOSE_WAIT:被动关闭,表示远程端 (连接的另一端) 已经关闭连接。
- TIME_WAIT:主动关闭, 表示本地端 (这边) 已经关闭连接,即主动关闭连接的一方保持的状态。 连接会被保持一会儿,以保证该连接上延迟的数据包可以被正确匹配处理。当超时4分钟后连接会被移除。
netstat -nalp | grep -E ‘:80 |:443 ' | awk ‘{print $6}’ | sort | uniq -c
TCP是全双工的,任何一端可以是source或destination. 在TCP/IP工作时,连接并不会被立即关闭. 在连接被关闭后,数据包也可能乱序或被重传。
- 注1: TIME_WAIT太多的问题可以通过优化服务器参数解决(开启keepalive)
- 注2: 但CLOSE_WAIT太多通常是程序的问题,需要代码判断(释放连接)或优化Nginx参数。
- 注3: MSL一般设置为30秒、1分钟,2分钟(RFC标准),主动关闭方会保持状态2MSL后彻底回收资源。
tcp_tw_reuse和tcp_tw_recycle
tcp_tw_reuse仅对outgoing有效(连接有incoming和outgoing之分).
设计协议时,尽量不要让客户端先关闭连接,应该让服务端控制.
不用开启 net.ipv4.tcp_tw_recycle, 最新内核4.12已结去掉该参数.
TCP/UDP参数
- Socket receive buffer size: Socket send and receive sizes are dynamically adjusted, so they rarely need to be manually edited.
- rmem_default : A kernel parameter that controls the default size of receive buffers used by sockets.
调优常用指标
- Ping 100以下
- 网络延迟50ms以下
- Dns解析尽量快
- 尽量少丢包
- 反向代理优化
调优辅助工具
perf-tools
开源的性能分析工具,基于perf和ftrace.

Linux Performance Observability Tools
sysdig
sysdig: Troubleshooting 工具,支持容器
SystemTap
- SystemTap[官方网站][1]
- CentOS[有用的脚本][2]
扩展阅读
- [Linux性能资源大全][3]
- [RedHat官方系统调优指南][4]
- [TCP的那些事儿][5] : TCP协议特点汇总
- [Linux TCP/IP 协议栈调][6]
- [tcp_tw_reuse和tcp_tw_recycle调整对于过多TIME_WAIT的调研][7]
- centos7-systemd-conf-limits
- Linux free shows high memory usage but top does not:关于内存使用的解释
- What is cache in “free -m” output and why is memory utilization high for cache?:官方详细解释
- Red Hat Enterprise Linux: 没有可以创建一个账号 [1]: https://sourceware.org/systemtap/ [2]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/systemtap_beginners_guide/useful-systemtap-scripts [3]: http://www.brendangregg.com/linuxperf.html [4]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/performance_tuning_guide/index [5]: http://coolshell.cn/articles/11564.html [6]: http://colobu.com/2014/09/18/linux-tcpip-tuning/ [7]: https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux