接手一台运行Ubuntu 20.04或22.04的服务器,第一件事不是装软件,而是确认时钟同步和硬件时钟的一致性。很多诡异的问题,比如数据库复制中断、HTTPS证书校验失败,根源都在于服务器时间漂移。直接检查timedatectl状态,确保NTP service是active的。如果发现系统时钟和硬件时钟不同步,执行sudo hwclock --systohc将系统时钟写入硬件时钟。对于云服务器,这个操作尤其重要,因为虚拟化环境里硬件时钟经常被宿主机重置。Ubuntu 22.04默认使用systemd-timesyncd,这是一个轻量级的NTP客户端,对于绝大多数场景足够用,不需要额外安装chrony。但如果你的服务器是金融交易或分布式存储节点,对时间精度要求极高,那还是得上chrony,它能提供微秒级的同步精度,并且能平滑地调整时钟,避免时间跳跃对应用造成冲击。
内核参数调优:针对高并发与内存密集型场景默认的内核参数是为了兼容普通桌面和低负载场景设计的,服务器环境下必须针对实际工作负载调整。先说文件句柄限制,高并发Web服务器或代理服务器经常会遇到“Too many open files”错误。直接修改/etc/security/limits.conf,为所有用户或特定用户设置nofile参数,比如root soft nofile 65535和root hard nofile 65535。但这还不够,内核层面的fs.file-max决定了系统全局能打开的最大文件数,通过sysctl -w fs.file-max=2097152来设置,并写入/etc/sysctl.conf持久化。
网络层面的调优对吞吐量影响巨大。net.core.somaxconn参数控制TCP监听队列的最大长度,默认值通常是128或4096,高并发下远远不够。建议设置为65535。net.ipv4.tcp_tw_reuse和net.ipv4.tcp_fin_timeout这两个参数配合使用,能快速回收处于TIME_WAIT状态的连接。Ubuntu 22.04的内核已经废弃了tcp_tw_recycle,不要再使用它,否则会导致NAT环境下的连接问题。对于作为反向代理或负载均衡器的服务器,net.ipv4.ip_local_port_range应该扩大,比如从1024到65535,避免端口耗尽。net.core.netdev_max_backlog和net.ipv4.tcp_max_syn_backlog分别控制网卡接收队列和SYN队列长度,都建议调大到8192或更高。这些参数调整后,用sysctl -p立即生效。
内存管理方面,vm.swappiness是个被过度讨论但经常被误解的参数。它控制内核将匿名页交换到swap的倾向,默认值是60。对于数据库服务器,尤其是Redis、MySQL这类对延迟敏感的应用,建议设置为10甚至1,让内核尽可能使用物理内存,避免不必要的swap I/O。但注意,设置为0在较新内核中意味着除非内存耗尽否则绝不swap,这可能在OOM时导致进程直接被kill,所以设置为1是更安全的选择。vm.vfs_cache_pressure控制内核回收dentry和inode缓存的倾向,默认100。如果你的服务器有大量文件操作,比如文件存储或静态资源服务,可以设置为50或更低,让内核更积极地保留文件元数据缓存,减少磁盘I/O。
存储栈优化:从文件系统到I/O调度器Ubuntu 20.04和22.04默认使用ext4文件系统,但如果你需要快照、压缩、写时复制等高级特性,ZFS或btrfs是更好的选择。Ubuntu 22.04对ZFS的支持更加成熟,可以直接通过apt安装zfsutils-linux。对于数据库工作负载,无论你选择哪种文件系统,挂载时加上noatime或relatime选项是基本操作。noatime完全禁止更新访问时间戳,能显著减少写操作,特别是对小文件读多写少的场景。如果你的应用不依赖atime信息,直接用noatime。relatime是折中方案,只有当atime早于mtime或ctime时才更新,也是默认选项,但显式指定更保险。
I/O调度器的选择在Ubuntu 20.04和22.04上有所不同。20.04的内核默认使用mq-deadline,而22.04已经切换到kyber或bfq,具体取决于存储设备类型。对于NVMe SSD,多队列架构下kyber调度器表现优异,它专门为低延迟设备设计,能有效减少I/O延迟抖动。你可以通过cat /sys/block/nvme0n1/queue/scheduler查看当前调度器,通过echo kyber > /sys/block/nvme0n1/queue/scheduler动态切换。对于HDD或SATA SSD,bfq能提供更好的公平性和吞吐量。但如果你使用RAID卡或者云服务器的虚拟磁盘,有时候none(noop)调度器反而是最佳选择,因为底层存储已经做了调度,上层再多一层调度反而增加延迟。这个需要根据实际fio压测结果来决定。
磁盘队列深度和预读值也是常被忽视的优化点。对于SSD,/sys/block/sda/queue/nr_requests可以适当增大,比如从默认的128调整到1024,让设备能同时处理更多请求。read_ahead_kb预读值对于顺序读场景很有帮助,默认128KB对于大文件读取偏小,可以调整到512KB或更大。但如果你的工作负载是随机读取,过大的预读反而会浪费内存带宽,这时候保持默认或减小更合适。
服务管理精简化:systemd深度配置Ubuntu从16.04开始全面采用systemd,但很多运维人员仍然只停留在systemctl start/stop/enable的层面。实际上systemd提供了强大的资源控制能力,通过service unit文件中的MemoryMax、CPUQuota、IOWeight等指令,可以精确限制每个服务的资源使用,避免单个服务拖垮整个系统。比如为MySQL服务设置MemoryMax=8G,防止OOM killer误杀关键进程。CPUQuota=200%表示该服务最多使用2个CPU核心的计算能力。这些配置直接写入对应服务的override文件,通过systemctl edit servicename创建,不会在软件包升级时被覆盖。
服务启动顺序和依赖关系也是故障排查的重灾区。使用systemd-analyze plot生成启动过程的可视化图表,能清晰看到哪些服务拖慢了启动时间。systemd-analyze blame列出每个服务的启动耗时。对于不需要的服务,直接mask掉而不是disable,mask能防止服务被其他依赖关系意外启动。Ubuntu 22.04中snapd服务经常占用大量启动时间和内存,如果你的环境不使用snap包,sudo systemctl mask snapd.service是合理的优化手段。
日志管理方面,journald默认的日志保留策略可能导致/var/log/journal目录膨胀。编辑/etc/systemd/journald.conf,设置SystemMaxUse=500M和MaxRetentionSec=2weeks,限制日志总大小和保留时间。对于日志量大的服务器,考虑将日志转发到集中式日志系统,本地只保留最近几天的量。同时设置Compress=yes启用日志压缩,能节省大量磁盘空间。
软件包管理策略:apt优化与最小化安装Ubuntu 20.04和22.04的apt默认行为有细微差别。22.04中apt会默认安装推荐包,这可能导致大量无用软件被带入系统。在/etc/apt/apt.conf.d/目录下创建自定义配置,设置APT::Install-Recommends "false";和APT::Install-Suggests "false";,让apt只安装必需的依赖。对于服务器环境,这个设置能显著减少攻击面和磁盘占用。
软件源镜像的选择直接影响更新速度。不要盲目使用官方源,根据服务器所在地理位置选择最近的镜像站。修改/etc/apt/sources.list时,注意20.04代号是focal,22.04代号是jammy,不要混用。对于生产环境,建议搭建本地apt缓存代理,比如apt-cacher-ng,这样多台服务器更新时只需要从外网下载一次,既节省带宽又加快部署速度。安全更新必须配置unattended-upgrades自动安装,但只启用安全更新源,避免非安全更新引入不兼容变更。
# /etc/apt/apt.conf.d/50unattended-upgrades 关键配置
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
安全加固:从用户权限到内核防护
ssh配置是服务器安全的第一道防线。修改/etc/ssh/sshd_config,禁止root密码登录PermitRootLogin prohibit-password,禁止空密码登录PermitEmptyPasswords no,修改默认端口虽然不能阻止针对性扫描,但能过滤掉大部分自动化攻击噪音。更有效的是配置基于密钥的认证,禁用密码登录PasswordAuthentication no。对于Ubuntu 22.04,sshd默认启用了更安全的加密算法协商,但如果你需要兼容老旧客户端,可能需要调整HostKeyAlgorithms和KexAlgorithms。
防火墙策略应该遵循最小权限原则。Ubuntu默认使用ufw作为iptables的前端,简化了配置。sudo ufw default deny incoming,sudo ufw default allow outgoing,然后只开放必要的端口,比如sudo ufw allow 22/tcp。对于Web服务器,通常需要开放80和443端口。但更精细的做法是限制来源IP,比如管理后台只允许办公网络IP访问。ufw的规则顺序很重要,先添加的规则优先级更高,使用sudo ufw status numbered查看规则编号,方便插入和删除。
内核安全模块不可忽视。AppArmor在Ubuntu中默认启用,为很多服务提供了强制访问控制。使用aa-status查看当前加载的策略和处于enforce模式的进程。对于自定义服务,编写AppArmor策略能有效限制其行为,即使服务被攻破,攻击者也无法访问策略允许之外的文件系统路径。Ubuntu 22.04对内核自防护也做了加强,/proc/sys/kernel/kptr_restrict默认设置为1,限制非特权用户读取内核指针地址,/proc/sys/kernel/dmesg_restrict限制查看内核日志的权限,这些都应该保持默认或进一步收紧。
性能监控体系:从被动查看到主动告警top和htop只能看到当前时刻的系统状态,对于性能瓶颈分析远远不够。sysstat包提供的sar命令是性能分析的基础工具,它能持续收集CPU、内存、I/O、网络等指标,并支持历史数据查询。安装后启用数据收集:sudo systemctl enable sysstat && sudo systemctl start sysstat。默认每10分钟采集一次数据,保存在/var/log/sysstat/目录下。当服务器出现性能问题时,用sar -f /var/log/sysstat/saXX回溯历史数据,能快速定位问题发生的时间点和资源使用趋势。
对于实时监控,Prometheus加Grafana的组合已经成为事实标准。node_exporter能暴露数百个系统级指标,从CPU各模式时间分配到磁盘I/O延迟分布,再到网络错误计数。关键是要设置合理的告警规则,而不是收集了数据却不看。比如磁盘使用率超过80%预警,CPU iowait持续超过30%说明存储存在瓶颈,内存available低于10%需要关注。Ubuntu 22.04的node_exporter可以直接通过apt安装,版本比20.04更新,暴露的指标更丰富。
eBPF技术正在改变性能分析的方式。Ubuntu 22.04的5.15内核对eBPF的支持更加完善,bcc-tools和bpftrace提供了动态追踪能力,无需修改内核或重启服务就能深入分析性能问题。比如tcplife工具能追踪每个TCP连接的生命周期,包括持续时间、传输字节数等,对于定位慢连接非常有帮助。biotop能实时显示哪些进程在进行磁盘I/O操作,类似top但针对块设备。这些工具在20.04上也能使用,但需要安装较新的内核版本或HWE内核。
Ubuntu 20.04到22.04的迁移注意事项如果你还在维护20.04的服务器,应该开始规划向22.04的迁移。22.04的OpenSSL升级到3.0版本,这是一个重大变化,某些老旧的应用程序可能不兼容。PHP版本从7.4跳到8.1,Python默认版本从3.8升级到3.10,这些语言版本的变化可能导致现有代码运行异常。在测试环境中充分验证后再进行生产迁移。内核从5.4升级到5.15,带来了更好的硬件支持和性能优化,但也改变了某些sysctl参数的默认值和行为,比如网络拥塞控制算法默认从cubic变为bbr,这在公网环境下通常能提供更好的吞吐量,但内网环境可能需要评估。
22.04引入了systemd-oomd作为用户空间OOM管理守护进程,它比内核OOM killer更智能,能根据内存压力提前干预。但如果你习惯了自己管理OOM行为,可能需要调整其配置或禁用它。22.04还默认启用了zswap压缩缓存,它在内存压力和swap之间增加了一层压缩内存,能有效减少实际swap I/O,对于内存紧张的场景是利好,但会消耗少量CPU资源进行压缩解压。
无论选择哪个版本,优化的核心逻辑不变:理解你的工作负载,测量当前性能瓶颈,针对性地调整参数,然后持续监控验证效果。没有一套配置能适用于所有场景,盲目的优化反而可能引入新的问题。每次只调整一个参数,观察足够长的时间,确认效果后再进行下一个优化,这才是服务器运维的正确节奏。
