拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux服务器性能调优:从关闭daemons到sysctl内核参数实战

Linux服务器性能调优:从关闭daemons到sysctl内核参数实战

简介:针对Linux服务器性能调优的实战文档,聚焦Red Hat Enterprise Linux AS与SUSE LINUX Enterprise Server两大企业发行版,适合系统运维、性能优化人员阅读。文档从实际场景出发,系统介绍了关闭不必要的daemons、禁用GUI、修改内核参数等基础技巧,并进一步展开处理器子系统(CPU亲和性、进程优先级)、内存子系统(脏页写回策略)、文件系统(ext4/XFS、挂载选项)及网络子系统(TCP/IP栈参数)的调优方法,各环节均配有具体命令示例,便于直接落地。资源为单个docx文档,共1个文件,大小仅373KB,内容精炼集中,可快速通读或随时查阅。已有238人学习下载,对于希望在不影响稳定性的前提下挖掘系统潜力的运维人员,这份整理能提供清晰的调优思路与常用工具参考。

1. Linux 性能调优的几种方法:这份文档能帮你从瓶颈里抠出多少性能

新接手一台 Linux 服务器,top 一打开 CPU 持续飙到 90%,free 一看内存所剩无几,ss -s 里 TIME_WAIT 连接挂了一大片。多数人的第一反应是「代码写得不行」或者「加机器」,但很多问题其实是系统默认参数和默认服务造成的。这份文档整理的就是另一条路:不换硬件、不动业务代码,靠关闭不必要的 daemons、切 runlevel、调 sysctl 内核参数,把 Red Hat Enterprise Linux AS 和 SUSE LINUX Enterprise Server 上被浪费的资源一点一点抠回来。它覆盖关闭 daemons、关闭 GUI、处理器/内存/网络四个子系统调优,适合刚接手服务器不知从哪下手的系统管理员,也适合 DBA 和运维工程师在压测前做一轮基线优化。

2. 关闭 daemons 与 GUI:先做减法,把闲置内存和 CPU 拿回来

2.1 关闭 daemons:从 sendmail 开始,逐个停掉不必要后台服务

服务器上跑着的后台服务,也就是 daemons,每一个都常驻内存、周期性被调度,不管你用不用它都在消耗 CPU 和内存。比如很多机器上默认启用的 sendmail,实际业务根本用不到邮件发送;还有一堆打印相关的服务,在纯计算服务器上毫无意义。停掉它们能释放内存、减少启动时间,因为开机时少拉起来一堆进程,同时进程数少了,内核调度和进程表维护的开销也跟着降。文档里还点了一句很实在的话:减少 daemons 数量同时也增强了服务器安全性,攻击面变小了。

Red Hat 和 SUSE 两家的命令风格不同,Red Hat 系用 service 加 chkconfig:

# Red Hat Enterprise Linux AS /sbin/service sendmail stop /sbin/chkconfig sendmail off

SUSE 系用 /etc/init.d 下的脚本:

# SUSE LINUX Enterprise Server /etc/init.d/sendmail stop /sbin/chkconfig -s sendmail off

service 命令本质上是去调 /etc/init.d 下的对应脚本,区别只是语法封装。chkconfig off 的作用是从当前 runlevel 的启动项里移除这个服务,让它在下次开机时不自动拉起,两个命令配合使用才完整:stop 是停掉当前进程,off 是防止它下次开机卷土重来。另有/sbin/chkconfig --list可以拉出所有服务的开关状态,比图形界面里看到的更全,因为有些 daemons 不会显示在 GUI 工具中。

Red Hat 的图形工具是/usr/bin/redhat-config-services,菜单路径 Main Menu -> System Settings -> Server Settings -> Services;SUSE 对应的是/sbin/yast2 runlevel。图形工具适合刚上手时浏览服务名,实际批量操作我一般还是用命令行。文档特别警告过 xfs daemon:关闭它会导致 X 启动不了,只有在确定不需要图形界面时才关,需要 startx 之前先把 xfs 拉起来。如果你现在维护的是 CentOS 7 以上的机器,这套 service/chkconfig 已经迁移到 systemctl 了,对应命令是systemctl disable sendmail和systemctl stop sendmail,思路完全一致。

2.2 关闭 GUI 与虚拟控制台:runlevel 3 才是服务器的常态

GUI 在服务器上是最典型的资源浪费:X server 本身吃几百 MB 内存,还占用 CPU 做渲染。文档的观点很直接:Linux 服务器上的管理任务全部可以通过命令行或 Web 工具完成,比如 webmin、Linuxconf、SWAT,需要看图形界面时再临时启动 GUI。多数服务器应该跑在 runlevel 3,也就是完整多用户模式但不进图形界面。

先确认当前在哪个 runlevel:

runlevel

输出如N 5,表示上次没有 runlevel,当前是 5。切换到 runlevel 3 用 init 命令:

init 3

runlevel 这点需要彻底记牢:0 是停机、6 是重启,谁都不该把默认 runlevel 设成这两个,否则服务器一开机就关机或无限重启。1 是单用户模式,用来做维护和修复;2 是多用户但不开 NFS;3 是完全多用户,服务器默认就选它;4 保留未用;5 是 X11 图形界面。

runlevel含义服务器上怎么用
0Halt 停机禁止设为默认
1单用户模式维护修复时进入
2多用户,不带 NFS无网络时可视为 3
3完全多用户服务器默认,推荐
4未使用保留
5X11 图形界面需要 GUI 时才进入
6Reboot 重启禁止设为默认

修改默认 runlevel 要编辑 /etc/inittab,把id:5:initdefault:改成id:3:initdefault:;SUSE 上执行 YaST runlevel 命令可以完成同样的事。还有一个容易被忽略的浪费点:系统默认保存 6 个虚拟控制台,F1 到 F6 各跑一个 getty 进程,每个都占少量内存。文档给的方案是用 mingetty 减少到 3 个,落地做法是在 /etc/inittab 里把 tty4 到 tty6 对应的那几行注释掉,然后init q重载。如果关掉了 GUI 但临时需要图形界面,远程连服务器时用ssh -X就可以把 X 会话转发到本地,不必在服务器上留着整套图形环境。

3. sysctl 与内核参数:改之前先搞清楚参数存在哪、怎么改才不丢

3.1 /proc/sys 与 /etc/sysctl.conf:临时生效和持久化的区别

Linux 内核参数的核心知识点是:参数不是存在某个配置文件里,而是以文件的方式暴露在 /proc/sys 目录下。/proc 是伪文件系统,用户态读它时内核现场生成内容,写它时内核实时修改对应参数。每个正在运行的进程在 /proc 下都有一个以 PID 命名的目录,里面是它的内存映射、文件描述符等信息;/proc/sys 下面则按子系统分目录,vm 管虚拟内存,net/ipv4 管 TCP/IP 栈,fs 管文件系统,kernel 管全局内核行为。

查看当前所有内核参数:

sysctl -a

这条命令会把 /proc/sys 下几乎全部参数打出来,输出很长,通常配合 grep 用,比如只看和 swap 相关的:

sysctl -a | grep swap cat /proc/sys/vm/swappiness

sysctl -a 与直接 cat /proc/sys 下的文件是等效的,区别只是显示格式。修改参数有两种写法,效果完全相同:

sysctl -w vm.swappiness=10 echo 10 > /proc/sys/vm/swappiness

sysctl -w 其实就是在帮你做 echo 写入。这里有个关键认知:这两种方式都只改内存里的值,重启服务器立刻还原。要让参数在重启后依然生效,必须写入 /etc/sysctl.conf,然后执行sysctl -p让内核重新加载一次。文档里提到的 SUSE powertweak 工具(/sbin/yast powertweak)和 Red Hat 的/usr/bin/redhat-config-proc图形界面,底层做的仍然是读写 /proc/sys 和 /etc/sysctl.conf 这两件事。另外文档提示过:默认情况下内核包含了不重启就用 sysctl 改参数的模块,但如果你安装系统时选择移除了该功能,那改完只能重启才能生效。

3.2 处理器子系统调优:超线程开关、内核选择与 EM64T

处理器是应用和数据库服务器的关键硬件,也是压测时最先被顶满的瓶颈。文档讲的第一件事是 Xeon 高端服务器上的 Hyper-Threading。超线程的原理是把一颗物理 CPU 虚拟成两颗逻辑 CPU,让同一个物理核心同时执行两个线程,操作系统会看到多出一倍的处理器。Red Hat Enterprise Linux AS 和 SUSE LINUX Enterprise Server 都支持,4 路服务器开超线程后,用 top 能看到 8 颗处理器。

但超线程不是白送的,文档给了很诚实的收益数据,这是这份文档里最值得记住的部分:

物理 CPU 数量超线程性能提升
2 颗15% - 25%
4 颗1% - 13%
8 颗0% - 5%

核心前提是必须跑 SMP 内核,单核内核不支持超线程。物理 CPU 越多,收益越差,8 路机器开了基本没提升,甚至在某些计算密集负载下因为共享执行单元反而下降。判断系统是否开了超线程,常见做法是看 /proc/cpuinfo:

grep "processor" /proc/cpuinfo | wc -l grep "physical id" /proc/cpuinfo | sort -u | wc -l

第一行是逻辑 CPU 数,第二行是物理 CPU 数,前者是后者两倍左右说明超线程开着。文档还提到 EM64T,也就是 Intel IA-32 处理器的 64 位扩展,Red Hat Enterprise Linux 3 Update 2 和 SUSE LINUX Enterprise Server 9 开始支持,它能寻址更多内存还能完全兼容 32 位应用。

内核包的选择对性能的影响也很大,两个发行版都提供多个内核包。旧机器上可以看 /boot 下内核文件名,带 smp 后缀的是对称多处理内核,跑多路 CPU 必须选这个;有些版本还提供 hugemem 大内存内核,适合内存超过 4GB 的机器。选错内核的表现是:CPU 只认到一半、内存只认到一部分,排查时先看uname -a和cat /proc/meminfo,确认内核匹配硬件规格再谈调优。

4. 内存与网络子系统调优:dirty 缓冲、TIME-WAIT 与连接队列的取值思路

4.1 虚拟内存参数:vm.bdflush 与 vm.kswapd 怎么取值

内存子系统的调优风险最高,因为动的是内核的脏页写回机制和交换行为,改坏了磁盘 IO 和响应延迟一起恶化。文档的建议非常务实:一次只改一个参数,然后用工具监测效果,确认没有副作用再动下一个。

vm.bdflush 控制 bdflush 内核线程把 dirty buffers 写回磁盘的时机。磁盘缓冲区比内存慢几个数量级,缓冲区里的数据变脏后,如果不及时落盘,内存被脏页占满,新请求只能等回收。文档给出的是一组 9 个参数:

sysctl -w vm.bdflush="30 500 0 0 500 3000 60 20 0"

9 个参数里只需要关心前 3 个逻辑位:第 1 个 nfract=30,表示排队写盘前,bdflush 允许脏缓冲区占系统缓冲区总量的最大百分比,超过 30% 就开始刷盘;第 2 个 ndirty=500,是 bdflush 一次最多即刻写的缓冲区数量,这个值越大,单次刷盘耗时越长,期间 IO 压力越大;第 7 个 nfract_sync=60,是发生同步前脏缓冲区允许达到的最大百分比,到 60% 时强制同步。这三个值合起来控制脏页写回的触发时机和单次刷盘量。

这里必须补一个版本边界:vm.bdflush 是 2.4 内核的参数,2.6 以后内核用 pdflush 和后来的 writeback 机制替代了它,dirty 参数迁移到了 vm.dirty_ratio 和 vm.dirty_background_ratio。你可以查内核文档确认。

vm.kswapd 是另一个内存守护进程,负责把内存页换出到交换分区:

sysctl -w vm.kswapd="1024 32 64"

三个参数的含义:tries_base=1024 约等于内核每次扫描交换页数量的四倍,对于交换非常频繁的系统,加大这个值能减少扫描次数、提升吞吐;tries_min=32 是每次最少换出的页数;swap_cluster=64 是 kswapd 每次连续写入 swap 的页数,这个值调小会提高磁盘 IO 的分散度,调大则可能让请求队列积压。改完用 vmstat 看 si 和 so 两列,si/so 持续不为 0 说明系统在频繁交换,这时候先判断是物理内存真不够,还是参数把交换调得太激进。文档还提了 buffermem、freepages、overcommit_memory、page-cluster 这些虚拟内存参数,它们都在 /proc/sys/vm 下,overcommit_memory 尤其要小心,改成 2 表示内核严格执行内存过量使用限制,数据库类应用容易被 OOM killer 误杀。

4.2 网络防攻击参数:SYN cookies、重定向与广播风暴

网络子系统调优会影响 CPU 利用率,尤其在大量 TCP 连接且包尺寸很小的场景下,内存消耗会肉眼可见地涨。文档这部分把安全和性能放在一起讲,因为很多防攻击的参数同时也在防止正常流量把服务器拖垮。

开启 SYN cookies 抵御 syn-flood 攻击,这是 DoS/DDoS 场景下最基础的一层防护:

sysctl -w net.ipv4.tcp_syncookies=1

对应到安全加固,还有一组常用参数:让服务器忽略来自不是网关的 ICMP 重定向,拒绝路由重定向攻击;如果这台机器本身不是路由器,关掉 send_redirects 让它不要向别人发重定向;忽略广播 ping 防止 smurf 攻击;忽略畸形 ICMP 错误回应减少内核日志噪音:

sysctl -w net.ipv4.conf.all.accept_redirects=0 sysctl -w net.ipv4.conf.all.send_redirects=0 sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1

文档提醒 ICMP 重定向是路由器传路由信息的机制:网关查完路由表后告诉主机「下一个网关是你应该用的」,合法场景里有价值,但攻击者也能伪造重定向把流量导走。只接受可信来源的重定向,不可信的一律丢弃。SUSE 上还有一个 rp_filter 参数,通过反向路径验证来源数据包,路由器默认转发所有包,开了过滤就能丢掉明显异常的流量:

sysctl -w net.ipv4.conf.all.rp_filter=1

4.3 TCP 会话保持参数:TIME-WAIT 复用、keepalive 与 backlog

连接数巨大的服务器上,TIME-WAIT 套接字是内存杀手。每个 TCP 连接关闭后要停留在 TIME-WAIT 状态一段时间,确保最后一个 ACK 到达对方,这个状态下套接字还占着内存。文档给的做法是允许新连接复用 TIME-WAIT 套接字,同时开启 TIME-WAIT 快速循环,对 Web 服务器非常有效:

sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -w net.ipv4.tcp_tw_recycle=1

注意 tcp_tw_recycle 在 NAT 环境下有严重副作用,后面第 5 章专门展开说。继续调连接生命周期参数:

sysctl -w net.ipv4.tcp_fin_timeout=30 sysctl -w net.ipv4.tcp_keepalive_time=1800

tcp_fin_timeout 是套接字关闭时保持 FIN-WAIT-2 状态的时间,默认可能到 60 秒以上,缩短到 30 秒能让内存更快腾出来处理新连接。TCP keepalive 参数负责探测那些「已打开但一直没用」的死连接,默认 2 小时才丢,连接量大时这 2 小时内存浪费很可观,改成 1800 秒是文档明确推荐的折中点。改这个值之前要评估业务特性:如果有大量客户端长连接挂机,时间设太短会频繁断开合法连接。

然后是发送和接收缓冲区的设置,先定上限再定动态区间:

sysctl -w net.core.wmem_max=8388608 sysctl -w net.core.rmem_max=8388608 sysctl -w net.ipv4.tcp_wmem="4096 65536 8388608" sysctl -w net.ipv4.tcp_rmem="4096 87380 8388608"

wmem 和 rmem 各设三个值:最小值、初始值和最大值。初始值是创建 TCP 套接字时分配的内存,最大值是上限,必须小于或等于 net.core.wmem_max 和 rmem_max,否则设置会被内核拒绝。缓冲越大吞吐越高,但每连接占用的内存也越多,连接数上万的机器上这两个参数直接决定了内存余量。

半开连接的处理也在这个环节:当大量客户端都是超长延迟连接、负载又重时,half-open 连接会堆满 backlog 队列。默认 1024 对高并发 Web 服务器不够,文档建议最少设到 4096,这同时能缓解 SYN flood:

sysctl -w net.ipv4.tcp_max_syn_backlog=4096

最后是 NFS 和 Samba 服务器会遇到的 IP 碎片重组问题。TCP 数据包传输出错时会触发碎片整理,有效数据包留在内存,损坏的转发走。文档建议把重组内存设成一个范围:

sysctl -w net.ipv4.ipfrag_low_thresh=268435456 sysctl -w net.ipv4.ipfrag_high_thresh=402653184

这个值表示碎片占用的内存落入低阈值和高阈值之间时,内核开始丢碎片直到回落到低阈值以下。取值单位在不同内核版本间有过变化,改完用cat /proc/sys/net/ipv4/ipfrag_low_thresh确认实际值再继续。

5. 调优避坑:五个改完参数才发现的翻车现场

5.1 关闭 xfs daemon 后 X 起不来

现象:按文档关了 xfs 服务,执行 startx 后 X 启动失败或直接白屏。

原因:xfs 是 X Window 的字体服务,X server 启动时依赖它提供字体渲染。很多刚接触 Linux 服务器的同学把 xfs 当作普通后台服务顺手关掉,结果图形界面起不来。

解决:需要 GUI 的时候先启动 xfs 服务再 startx,不需要 GUI 就保持关闭。命令/sbin/service xfs start和 startx 顺序不能反。

5.2 sysctl -w 改完重启全部失效

现象:用 sysctl -w 调完参数当时生效,压测一切正常,第二天重启服务器,参数全部回到默认值。

原因:sysctl -w 和 echo 写入 /proc/sys 都只改内存中的值,重启后内核重新读默认值,/etc/sysctl.conf 没写进去等于白调。

解决:调完参数立刻写入 /etc/sysctl.conf,然后sysctl -p验证。我现在养成的习惯是每调一个参数就顺手在配置文件里加一行注释,写清日期、改了什么、为什么改,避免一个多月后看着自己写的配置发愣。

5.3 tcp_tw_recycle 在 NAT 后丢包

现象:开启 net.ipv4.tcp_tw_recycle=1 后,部分客户端连接时好时坏,抓包看到服务器直接丢 SYN 包。

原因:tcp_tw_recycle 依赖 TCP 时间戳判断旧连接,同一 NAT 网关后面挂着大量不同系统、不同 RTT 的客户端,时间戳机制会把时间戳偏小的合法 SYN 误判成旧包丢弃。文档写这个参数时是 2.4 内核时代,现在 Linux 4.12 以上的内核已经直接移除了这个参数。

解决:NAT 环境下关闭 tcp_tw_recycle,只保留 tcp_tw_reuse,把精力放在调 tcp_fin_timeout 和 tcp_max_tw_buckets 上。所有改 TCP 参数的机器,先确认部署环境有没有 NAT 层再动手。

5.4 vm.bdflush 在 2.6+ 内核不存在

现象:按文档执行sysctl -w vm.bdflush="30 500 0 0 500 3000 60 20 0",系统返回 No such file or directory。

原因:vm.bdflush 是 2.4 内核的脏页写回参数。2.6 内核换成 pdflush 机制,后来又被 writeback 取代,参数迁移到了 vm.dirty_ratio 和 vm.dirty_background_ratio。

解决:2.6+ 内核上改用现代参数。调的时候先看当前值再改,sysctl vm.dirty_ratio和sysctl vm.dirty_background_ratio,默认通常分别是 20 和 10,写密集应用可以把 dirty_background_ratio 调低让脏页更早开始刷盘,避免一次性大量写回把 IO 打满。

5.5 超线程开了性能反而下降

现象:数据库类负载在开启超线程的机器上压测,CPU 利用率看着上去了,QPS 反而比关闭时低。

原因:超线程是让一个物理核心分时执行两个线程,本质是共享执行单元的虚拟化。对缓存敏感的计算密集负载,两个线程抢 L2/L3 缓存和流水线部件,互相拖后腿。文档给的数据也印证了:8 路机器开超线程只有 0-5% 的收益。

解决:计算密集、缓存敏感型业务,在 BIOS 里关掉超线程,或者操作系统层用 taskset 绑核,把关键进程隔离到固定物理核上。跑日志处理和网络转发这类 IO 密集任务再考虑开超线程。

5.6 runlevel 误切到 0 或 6

现象:执行 init 0 后服务器直接关机,或者在机房误操作把默认 runlevel 设成 6,机器陷入无限重启。

原因:runlevel 0 是停机,6 是重启,都是危险目标。常在命令行下切 runlevel 的时间久了,手指记忆容易出错。

解决:切换之前先runlevel确认当前状态,再想清楚目标 runlevel。改 /etc/inittab 里 initdefault 时只允许出现 2、3、5 三个值。维护脚本里加防御性判断:[ "$target" = "0" ] && exit 1。

6. 调优后的验证与固化:从 vmstat 到 /etc/sysctl.conf

参数改完不是结束,验证和固化才算调完。我的固定流程是先存基线再改动:调优前跑一轮压测或记录业务低峰期的 vmstat 输出,改完参数在相同场景下再跑一轮,两次数据对比才有说服力,否则你根本分不清性能变化是参数生效了还是网络波动。

验证工具就那么几个,但要看对指标。vmstat 1 5 每秒打一次共打 5 次,重点看 us 用户态 CPU、sy 系统态 CPU、wa IO 等待和 si/so 交换页;free -m 看 cache 和 swap 的实际占用;连接数大的机器用 ss -s 看 socket 状态分布,TIME_WAIT 占比是不是降下来了。

vmstat 1 5 free -m ss -s

对照基线判断:wa 高说明磁盘是瓶颈,调 dirty 相关参数方向对;si/so 持续非零说明内存吃紧,该排查业务内存占用而不是继续压参数;TIME_WAIT 数量下降但连接错误率上升,多半是 tw_reuse 或 fin_timeout 调太狠。

验证通过后,把所有参数按子系统分块写进 /etc/sysctl.conf,每段加注释,比如# network tuning for 2024-06这类标记,然后 sysctl -p 确认无报错。文档里的很多参数是 2.4/2.6 内核时代的经验值,放到新内核上要先用 sysctl -a 确认参数存在,再以当前默认值为基础小步调整。

从那以后,我每次调优都强制自己先存一份基线快照再动手,所有改动记录归档,一次只动一个参数。性能调优这东西,玄学感都来自改了一堆参数却不知道是哪条起了作用。按「基线 → 单参数改动 → 验证 → 固化」走一圈,帮你在下一次服务器变慢时,好歹有个清晰的后悔药路径。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表