操作系统层裁剪:内核模块精简、禁用不必要的系统服务、调整内核参数

系统裁剪这件事,很多人一上来就盯着应用层优化。但我个人的习惯是——先看操作系统本身。你想想看,一个系统里跑着几十个用不上的服务、加载了一堆你根本不会用到的内核模块,它怎么可能快得起来?

说白了,操作系统层裁剪是性价比最高的优化手段。不需要改代码,不需要换硬件,只要把那些「吃闲饭」的组件拿掉,性能就能明显提升。我在项目中遇到过一台服务器,裁剪前 idle 进程只占 30%,裁剪后直接飙到 75%。嗯,这就是我们今天要聊的内容。

内核模块精简:把不需要的「零件」拆掉

Linux 内核默认编译了很多模块。这些模块就像工具箱里你永远不会用到的扳手——它们占地方,还拖慢启动速度。

第一步:看看你加载了哪些模块

# 查看当前已加载的模块
lsmod

# 查看所有可用模块(包括未加载的)
find /lib/modules/$(uname -r) -name "*.ko" | wc -l

我见过一个默认安装的 CentOS 系统,内核模块数量超过 3000 个。而实际用到的,往往不到 200 个。剩下的那些,就是你可以裁剪的对象。

第二步:确定哪些模块可以移除

我个人习惯按这个思路来筛选:

  • 硬件无关的模块:比如你用的是 Intel 网卡,那所有 Realtek、Broadcom 的网卡驱动都可以删掉
  • 文件系统模块:只用 ext4,那 btrfs、xfs、zfs 的模块都可以去掉
  • 网络协议模块:不需要 IPv6 就干掉 ipv6.ko,不需要 netfilter 就清理 iptables 相关模块
  • 安全模块:SELinux、AppArmor 如果不用,直接禁用
⚠️ 注意: 我曾经因为删掉了 USB 存储驱动,导致服务器重启后无法挂载外置备份盘。所以建议你先在测试环境验证,确认不影响业务再上生产。

第三步:重新编译内核或使用 modprobe 黑名单

如果你不想重新编译内核(说实话,大部分场景没必要),可以用黑名单机制:

# 创建黑名单配置文件
echo "blacklist ipv6" >> /etc/modprobe.d/disable-ipv6.conf
echo "blacklist btusb" >> /etc/modprobe.d/disable-bt.conf

# 更新 initramfs
dracut --force

重新编译内核的话,我建议用 make localmodconfig。这个命令会根据当前系统加载的模块自动生成一个精简配置。我在一个嵌入式项目里用过,内核体积从 120MB 降到了 18MB,启动时间从 45 秒缩短到 8 秒。

禁用不必要的系统服务:别让它们偷走你的 CPU

系统服务是另一个「隐形杀手」。很多服务默认开机自启,但你根本用不上。

先看看当前有哪些服务在跑:

# systemd 系统
systemctl list-units --type=service --state=running

# 查看开机自启的服务
systemctl list-unit-files --type=service --state=enabled

我整理了一份常见的「可禁用服务清单」,你可以对照着检查:

服务名称 用途 建议
bluetooth.service 蓝牙支持 服务器环境直接禁用
cups.service 打印服务 99% 的服务器用不到
avahi-daemon.service 零配置网络发现 内网环境可禁用
postfix.service 邮件传输 不需要发邮件就关掉
firewalld.service 防火墙 如果用了 iptables 或 nftables 可禁用
NetworkManager.service 网络管理 服务器建议用 systemd-networkd 替代
💡 小技巧: 禁用服务时,用 systemctl mask 而不是 systemctl disable。mask 会彻底阻止服务被启动(包括被其他服务依赖触发),而 disable 只是不让它开机自启。

禁用命令示例:

systemctl stop bluetooth.service
systemctl mask bluetooth.service

我曾经在一台 2C4G 的云服务器上,禁用了 12 个不必要的服务。重启后,内存占用从 1.2GB 降到了 480MB。你想想看,这省下来的 700 多 MB 内存,留给业务进程多好。

调整内核参数:用最小的改动换最大的收益

内核参数调整是系统裁剪的「点睛之笔」。不需要删东西,改几个数值就能看到效果。

网络栈优化

如果你的系统主要做网络 I/O,这几个参数值得关注:

# 在 /etc/sysctl.conf 中添加以下内容

# 增大 TCP 连接队列长度
net.core.somaxconn = 65535

# 减少 TIME_WAIT 状态的连接数
net.ipv4.tcp_fin_timeout = 15

# 开启 TCP 快速回收(注意:仅适用于非 NAT 环境)
net.ipv4.tcp_tw_reuse = 1

# 增大 socket 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
⚠️ 注意: tcp_tw_recycle 这个参数在 Linux 4.12 之后已经被移除了。如果你还在用旧内核,千万别开这个——它在 NAT 环境下会导致严重的连接问题。我踩过这个坑,线上故障排查了整整两天。

内存管理优化

对于内存敏感的场景,我建议调整这些:

参数 默认值 推荐值 说明
vm.swappiness 60 10 减少 swap 使用倾向,优先用物理内存
vm.dirty_ratio 20 10 降低脏页比例,减少 I/O 抖动
vm.vfs_cache_pressure 100 50 减缓 dentry/inode 缓存回收
kernel.numa_balancing 1 0 关闭 NUMA 自动平衡(单 socket 场景)

文件系统优化

如果你用的是 SSD,记得调整 I/O 调度器:

# 查看当前调度器
cat /sys/block/sda/queue/scheduler

# 设置为 none(NVMe SSD 推荐)或 mq-deadline
echo "none" > /sys/block/sda/queue/scheduler

# 永久生效(通过 udev 规则)
echo 'ACTION=="add|change", KERNEL=="sd*", ATTR{queue/scheduler}="none"' > /etc/udev/rules.d/60-iosched.rules

为什么这么做?传统的 CFQ 调度器会对 I/O 请求做复杂的排序和合并,这在 HDD 时代有用,但在 SSD 上反而增加了延迟。直接设为 none,让硬件自己处理,性能提升很明显。

本章核心知识体系

下面这张图总结了操作系统层裁剪的三个维度和它们之间的关系:

操作系统层裁剪核心知识体系 内核模块精简 禁用系统服务 调整内核参数 lsmod 分析 黑名单机制 localmodconfig systemctl 审计 mask 禁用 服务依赖检查 网络栈优化 内存管理 I/O 调度器 裁剪顺序:先精简模块 → 再禁用服务 → 最后调参数 每步完成后都要做回归测试,确保业务不受影响 预期收益:CPU 占用 ↓ 40% · 内存 ↓ 30% · 启动时间 ↓ 50%

总结一下:操作系统层裁剪不是一锤子买卖。我建议你每做一次改动,就用 perf stat 或 time 命令记录一下前后的性能数据。这样你才能知道哪些改动真正有效,哪些只是心理安慰。

另外,别忘了做回归测试。我曾经因为禁用了 systemd-journald,导致日志丢失,排查线上问题花了三倍时间。嗯,这个教训挺深刻的。