news 2026/10/10 14:56:32

Linux性能优化与安全加固实战:从观察到落地的核心手段

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux性能优化与安全加固实战:从观察到落地的核心手段

自学Linux这件事,很多人卡在第十五天到第二十天这个坎上。前面的基础命令、文件权限、进程管理都学完了,突然发现真正干活的时候完全不知道从哪里下手。第十八天这个节点,我个人体会是最容易出成就感的时候,因为你开始碰两件特别实在的事:系统性能优化和安全加固。这篇文章就把我这段时间实战中反复用到的核心手段整理出来,不堆概念,只讲我实际敲过的命令、踩过的坑、以及为什么这么做。

先说清楚这篇文章适合谁。如果你刚学完Linux基础,想知道服务器卡了怎么排查、怎么防止被爆破、怎么把一台裸奔的机器收拾得像样,那这篇就是给你写的。如果你已经有几年运维经验,可以直接跳到第三、四节看我的实操细节和问题排查记录,也许能帮你补上一些平时容易忽略的角落。

1. 先把思路理清楚:为什么性能和加固要一起做

1.1 性能优化不是盲目调参

我见过很多刚入门的同学,一听到"性能优化"就急着改内核参数,vm.swappiness调到10,net.core.somaxconn拉到65535,看起来挺专业,实际上系统该卡还是卡。性能优化这件事,第一步永远是观察,第二步才是调整。你连瓶颈在哪都不知道就动手,跟生病了不看医生直接给自己开药没什么区别。

而且性能问题和安全问题在真实环境里是纠缠在一起的。一个典型的场景:服务器CPU持续100%,你第一反应是程序负载高,结果一查发现是某个服务被爆破失败后反复重试,把CPU吃满了。这种情况下,你只做性能调优不解决任何问题,得先把入口堵住。同样,安全加固做得太激进,把该开的端口封了、把正常用户的权限砍了,服务起不来、业务报错,最后性能表现一样是崩的。把这两件事放在一起学,不是贪多,而是它们在实操中本来就是一件事的两面。

1.2 优化和加固的先后顺序与原则

我的习惯是:先做安全基线,再做性能基线,最后才谈调优。原因很简单,安全配置会改变系统的行为方式,比如防火墙策略、SSH配置、账号权限,这些都会影响你能用什么方式去观察和调试系统。如果你先优化了性能,再改安全策略导致服务重启,之前的优化基线就全乱套了。

还有一个原则必须刻在脑子里:永远只改一个变量。很多新手喜欢一次改五个内核参数,出问题之后根本不知道是哪个参数导致的。我通常的做法是,一次只动一个配置,记录改动前的数值、改动后的数值、以及观察时间窗口。这个习惯在后面的问题排查章节会体现出来,它能帮你省下大量回滚的时间。

2. 性能优化:从观察数据到定位瓶颈

2.1 第一板斧:负载、CPU、内存的全面体检

接手一台机器,我第一件事永远是跑一套体检命令,而不是直接看某一个指标。这套命令组合我基本闭着眼都能敲出来:

# 先看整体负载和运行队列 uptime # 再看CPU和内存的实时状态 top -c # 看内存的详细分配情况 free -h # 看磁盘IO和CPU等待时间 iostat -x 1 3 # 看系统层面的上下文切换和中断 vmstat 1 5

这里有个非常关键的认知:load average不等于CPU使用率。load average是运行队列中可运行线程和不可中断睡眠线程的平均数,它包含了等待CPU的进程,也包含了等待磁盘IO的进程。很多服务器load average高,但CPU使用率只有30%,这时候真正的瓶颈往往在磁盘IO,而不是CPU。你光看top觉得CPU没事,可能就漏掉了真正的元凶。

vmstat有一个字段叫wa,它表示CPU等待IO完成的时间占比。如果这个值长期大于30%,基本可以断定磁盘IO吃紧。我在一台跑MySQL的云服务器上就碰到过这个情况,vmstat的wa常年40%以上,CPU的us和sy都很低,但应用就是慢。后来换了SSD云盘,wa直接掉到5%以内,问题迎刃而解。这就是数据说话的力量。

内存这块,free -h的解读也有讲究。注意看available这个字段,它才是真正可分配内存的估算值,而free那一列只是完全空闲的物理内存。Linux的内存管理机制决定了它会尽量利用空闲内存做文件缓存,所以free显示很小不代表内存不够,关键看available是不是充足。这个误解坑了很多人,我一开始也以为内存用满了,其实系统的页缓存随时可以被回收。

2.2 第二板斧:磁盘IO与文件系统的调优

磁盘瓶颈是性能问题里最隐蔽的一类,因为它不像CPU那样能直接从top里看到。排查IO问题,我的标准组合是iostat加iotop:

# 查看每个磁盘的利用率、吞吐量、IO队列长度 iostat -dx 1 5 # 实时查看每个进程的IO读写 iotop -o

关注iostat输出里的%util。这个值反映的是磁盘设备繁忙程度,如果长期在90%以上,说明磁盘基本饱和了。但这里有个细节:%util高不一定是坏事,如果是顺序读写,磁盘虽然忙,但吞吐量高,任务完成得快;真正需要担心的是avgqu-sz(平均队列长度)和await(平均IO响应时间)同步上涨,这说明IO请求在排队等处理,性能确实下降了。

文件系统层面的调优,我用得最多的是mount参数优化。比如对于ext4文件系统,如果业务日志多、小文件多,可以考虑在挂载时看情况调整noatime。默认情况下,每次读取文件都会更新atime(访问时间),这会产生大量的元数据写入。挂载时加上noatime,可以显著减少不必要的磁盘写操作。改完记得重新挂载:

# 以 noatime 方式重新挂载 mount -o remount,noatime /

在调整IO调度器方面,现代内核大多使用mq-deadline或none(也就是noop),一般来说不建议手动乱改。SSD上用none、机械盘上用mq-deadline,这是比较稳妥的默认选择。检查方式很简单:

cat /sys/block/sda/queue/scheduler

2.3 第三板斧:内核参数与进程资源的精细调整

前面说过不要盲目调参,但不代表内核参数不能动。有几个参数是我在实战中确实验证过有效果的,而且改动风险相对可控。

第一个是vm.swappiness。这个参数控制系统倾向于使用swap还是回收页缓存。默认值通常是60,对于内存充足的应用服务器,我一般会调到10左右,减少不必要的swap换入换出。举个例子,一个16G内存的机器,可用内存还有8G,但系统可能因为缓存压力就把冷数据换到swap里去了,这会导致后续访问这些数据时产生IO延迟。调低swappiness可以让系统更积极回收页缓存,而不是急着用swap:

# 临时生效 sysctl vm.swappiness=10 # 永久写入配置 echo 'vm.swappiness = 10' >> /etc/sysctl.conf sysctl -p

第二个是文件描述符和进程数的限制。很多高并发应用报"too many open files",就是因为ulimit限制太低。检查方式:

ulimit -n ulimit -u

临时调整:

ulimit -n 65535

但注意,ulimit只在当前shell会话生效。真正可靠的做法是修改系统级配置,同时修改服务的systemd单元配置。系统级配置在/etc/security/limits.conf,写法如下:

* soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535

如果服务是systemd管理的,还需要在service文件里加上LimitNOFILE=65535和LimitNPROC=65535,然后daemon-reload加重启服务。这一步很容易被忽略,很多人改了limits.conf发现不生效,就是因为systemd会覆盖这个设置。

2.4 排查工具的安装说明

iostat、iotop、sar这些工具很多最小化安装的Linux系统上默认没有。装的时候注意区分包名,Debian系用sysstat包,RedHat系用sysstat包也都覆盖大部分命令。这里给个参考:

# Debian/Ubuntu apt update && apt install -y sysstat iotop # CentOS/RHEL yum install -y sysstat iotop

sysstat包安装后,sar命令默认还没开始采集数据,需要启用sadc的定时任务。Debian系通常是启用/etc/default/sysstat里的ENABLED="true",然后重启sysstat服务。这一步很多人漏了,结果执行sar半天没数据,其实是历史数据根本没在采。日常巡检建议保留sar数据,这相当于给系统装了黑匣子,出问题时能回看历史曲线,对排查"昨晚两点到底发生了什么"这类问题帮助极大。

3. 安全加固:小成本换大收益的关键配置

3.1 账号与权限管理,先管住"入口"

安全加固里优先级最高的,永远是账号和权限。因为这是系统的入口,入口失守其他都是空谈。我接手任何一台机器,第一步就是排查当前系统里有哪些用户、哪些用户有sudo权限:

# 查看所有用户 cat /etc/passwd # 查看哪些用户属于sudo/wheel组 getent group sudo getent group wheel # 查看最近登录记录 last -20

发现不认识的用户、长期不用的账号,我的建议是直接锁定而不是删除。删除用户可能破坏它原来所属文件的属主关系,锁定则安全且可逆。锁定和禁用命令如下:

# 锁定用户密码 passwd -l username # 锁定用户登录 usermod -L username

sudo权限的授予要遵循最小化原则。很多同学图省事,直接把用户加到sudo组里,结果这个用户被入侵后,攻击者直接就拿到root权限了。正确做法是单独在/etc/sudoers.d/下建配置文件,只授权该用户需要执行的那几条命令:

# 只允许指定用户执行 systemctl 和 journalctl echo 'deploy ALL=(root) /usr/bin/systemctl, /usr/bin/journalctl' > /etc/sudoers.d/deploy chmod 440 /etc/sudoers.d/deploy

记住sudoers文件权限必须是440,否则visudo -c会报错。另外,修改sudoers一定要用visudo命令,它会做语法检查,防止你写错导致整个sudo不可用。就算是在/etc/sudoers.d/下新建文件,也用visudo -f /etc/sudoers.d/deploy来编辑,这个习惯能救你很多次。

3.2 SSH远程访问的加固几条硬规则

SSH是云服务器被爆破的头号目标。你看/var/log/auth.log或/var/log/secure就会发现,公网IP的机器每天都有大量扫描尝试。SSH加固我总结了几条硬规则,按优先级排列:

第一,禁止root直接登录。root账号是攻击者最想拿下的目标,关闭它直接登录可以大幅度降低风险。第二,有条件就上密钥登录,彻底关闭密码登录。第三,修改默认端口虽然不能治本,但可以大量减少自动扫描脚本的骚扰。第四,限制允许登录的用户白名单。

具体配置在/etc/ssh/sshd_config里:

# 禁止root登录 PermitRootLogin no # 启用密钥登录并关闭密码登录 PubkeyAuthentication yes PasswordAuthentication no # 修改默认端口,比如从22改成2222 Port 2222 # 限制登录用户白名单 AllowUsers deploy ops

改完必须验证配置再重启服务,否则很容易把自己锁在外面。验证和重载命令:

# 验证配置语法 sshd -t # 优雅重载 systemctl reload sshd

这里有个血泪教训:关闭密码登录之前,一定要确认自己的公钥已经写在目标机器的~/.ssh/authorized_keys里,并且密钥文件的权限是正确的。公钥文件权限要求.ssh目录是700,authorized_keys是600,否则严格模式下SSH会拒绝加载公钥。改完配置最好另开一个终端窗口测试登录,确认没问题再关掉当前连接。

密钥登录还有一个细节:私钥在本地客户端的权限必须是600。很多坑都出在权限过宽,SSH客户端直接拒绝使用这个私钥,报错信息却是Permission denied,让人误以为是服务器配置问题,排查半天。

3.3 防火墙策略与服务暴露面

安全加固的另一个核心原则是缩小暴露面:机器上没用的服务尽量不装,装了不用的服务就停掉并设置开机禁用。检查当前监听的端口:

# 查看所有监听端口及对应进程 ss -tlnp

用ss而不是老掉牙的netstat,新系统上可能都没装netstat。看到某些端口在监听,你甚至不一定知道是什么服务,用ss -tlnp里的process字段直接就能看到进程名和PID。

防火墙这块,不同系统用的工具不一样。RedHat系用firewalld,Debian系用ufw,都比较直接。我的习惯是默认丢弃所有入站流量,只放行必需端口。以ufw为例:

# 设置默认策略 ufw default deny incoming ufw default allow outgoing # 放行SSH端口,注意和自己的sshd配置保持一致 ufw allow 2222/tcp # 放行Web服务端口 ufw allow 80/tcp ufw allow 443/tcp # 启用防火墙 ufw enable

启用防火墙之后的第一个动作,是马上从外部测试一下SSH还能不能连上。因为云服务商的控制台安全组和系统内的防火墙是两层独立的配置,任何一层漏了都可能把自己的SSH挡在外面。

还可以考虑安装fail2ban来专门对付暴力破解。它通过监控日志里的失败登录记录,动态封禁来源IP。配置好之后,它能在几分钟内拦截掉绝大多数持续的爆破尝试。不过要注意,fail2ban依赖系统日志服务,使用systemd日志时可能需要额外配置后端。安装方式很简单:

apt install -y fail2ban # 或者 yum install -y fail2ban

安装后建议改一下配置,默认的封禁时间和重试次数可以根据自身需求调整。配置文件在/etc/fail2ban/jail.local,里面可以给sshd单独设置maxretry和bantime。

3.4 日志与入侵痕迹的追踪

安全加固做得再好,也得有事后追踪的手段。日志就是你的取证工具。每次排查安全事件,我第一步都会去看认证日志:

# Debian/Ubuntu tail -100 /var/log/auth.log # RedHat/CentOS tail -100 /var/log/secure

重点关注几个特征:大量来自相同IP的"Failed password"记录、非正常时间段的"Accepted publickey"记录、以及陌生的用户登入记录。这几类直接对应爆破攻击、渗透成功、账号异常使用。

如果怀疑日志被修改过,可以通过journalctl查看systemd日志,这部分不在传统的/var/log下,很多攻击者不会清理:

journalctl --since "24 hours ago" | grep -i "failed\|accepted"

顺手把/var/log/wtmp和/var/log/btmp的登录记录检查一遍。last命令查正常登录,lastb查失败登录。失败登录记录里如果某IP出现了几十上百次,基本可以确认是被爆破盯上了,赶紧按前面的方法加固。

4. 实操全流程:我的一次完整优化加固记录

4.1 性能基线数据采集

理论说了一堆,下面记录我最近一次给一台CentOS 7.9云服务器做优化加固的完整过程,这台机器跑着一个Nginx加Java应用,配置是2核4G。接手时的情况是:业务方反馈高峰时段接口响应慢,同时怀疑有外部攻击。

我先采集了性能基线。用sar把历史数据拉出来:

# 查看今天到目前为止的CPU使用率 sar -u # 查看内存使用趋势 sar -r

采集结果很明确:CPU使用率有小幅波动,但整体不高;令人意外的是内存趋势里看到kbswpfree持续下降,说明系统在持续使用swap。再用free -h确认:

free -h

结果显示available只有不到500M,同时swap用掉了1.2G。这就解释了业务响应慢的问题:JVM堆内存设置得过大,加上机器本身内存吃紧,系统频繁在内存和swap之间换页,Java应用在这种状态下响应自然快不了。

负载这边,uptime显示的load average在2.5左右,2核机器这个值已经偏高了,但CPU的us不高,结合前面的判断,问题主因在内存和swap。这台机器性能优化的核心就不是调CPU参数,而是解决内存压力和swap抖动。

4.2 安全加固落地步骤

性能诊断做完了,先放一边。按我前面说的原则,先做安全加固,把环境稳定下来再动性能参数。

第一步,清理账号。cat /etc/passwd检查后发现有两个长期未使用的普通账号,直接锁定:

passwd -l olduser1 passwd -l olduser2

第二步,加固SSH。生成密钥对,这里建议用ed25519算法,比RSA密钥更短更安全:

ssh-keygen -t ed25519 -C "deploy@myserver"

然后把公钥追加到服务器的/etc/ssh/deploy_authorized_keys或者对应用户的~/.ssh/authorized_keys里。改完sshd_config之后先sshd -t验证,再systemctl reload sshd。同时把SSH端口从22改成22022,把salt和pepper端口都关掉只留必需端口。这里改完端口后,我额外做了一件事:先在同机房的另一台测试机上确认了新端口可以登录,才在防火墙里放行22022,顺序很重要。

第三步,配置防火墙。用firewalld执行:

systemctl start firewalld firewall-cmd --permanent --remove-service=ssh firewall-cmd --permanent --add-port=22022/tcp firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=443/tcp firewall-cmd --reload

注意firewalld的默认区域是public,默认策略就是拒绝大部分入站,所以不需要像ufw一样单独设置default deny。确认规则加载后,立刻用客户端连一次22022端口验证通过。这一步做完,系统暴露面已经小了一大圈。

第四步,安装并配置fail2ban。在CentOS上安装后,修改/etc/fail2ban/jail.local,给sshd配置独立的封禁策略:

[sshd] enabled = true port = 22022 maxretry = 3 bantime = 3600 findtime = 600

配置好后启动并观察日志,确认fail2ban在正常工作,不再有大量扫描记录能连续命中。

4.3 安全环境下的性能调优落地

安全基线完成后,回到性能优化。这一步我只动了一个核心参数:vm.swappiness。

先看当前值:

sysctl vm.swappiness # 输出 vm.swappiness = 30

考虑到这台机器内存确实吃紧,我没有一上来就调到10,而是先调到15,观察一天。这里要说明一个思路:内存不足时,完全禁止swap可能导致进程被OOM Killer干掉,所以swappiness不要调到0,保留一点swap作为兜底反而更安全。注意这里是调低swap使用倾向,而不是关闭swap本身,这是两个完全不同的操作。

改法:

echo 'vm.swappiness = 15' >> /etc/sysctl.conf sysctl -p

同时检查了JVM的堆内存配置,发现-Xmx设置3G,比物理内存还激进,难怪系统老在swap。这个属于应用层面的调整,和系统参数要分开看。调整应用配置可能需要和开发同事沟通,但这里只演示系统层面的做法。将JVM参数先改为-Xmx2G,配合swappiness调整,观察一天后free -h显示swap占用从1.2G下降到400M,uptime的load average降到1.2左右,明显好转。

这轮实操给我的体会是:优化动作要小步快跑,每一步都记录前后数值,用数据验证效果,而不是感觉"好像快了一点"。

5. 常见问题与排查技巧实录

5.1 负载虚高:load average高但CPU不高

这个问题出现频率极高。表现为uptime显示的负载在3以上,但top看CPU使用率只有20%。大多数时候是磁盘IO在排队,用iostat -x 1 3确认就能看到%util很高。解决办法就是按前面章节找IO大户,用iotop -o看是哪个进程在写。

还有一种情况是僵尸进程堆积。大量的僵尸进程会占着进程表项,影响新进程的fork。用ps aux | awk '$8 ~ /^Z/'查看僵尸进程,找到它的父进程,重启父进程或者用它kill父进程,僵尸进程就会一起被回收。注意僵尸进程不能被kill -9直接杀掉,因为它已经死了,只差父进程来收尸。

5.2 加固SSH后自己登录不上了

这是安全加固最常见的翻车现场。原因通常是改sshd_config时把PasswordAuthentication改成no,但客户端的公钥没配置好。遇到这种情况,唯一的办法是通过云控制台的VNC或紧急登录功能进系统,把配置改回来。

所以我强烈建议:一切可能锁死远程登录的操作,都先验证再应用。sshd -t只是语法检查,不能保证你的密钥真能登录。我自己的流程是:先开一个新的SSH会话测试登录成功,再关闭旧的会话。如果是改防火墙,也是同理,先确认新规则放行了SSH端口,再执行firewall-cmd --reload。

5.3 调了sysctl参数后系统不稳定

内核参数改动后系统行为异常,多半是参数值设得太激进。比如vm.swappiness设成0,导致内存回收机制变得激进,某些应用出现卡顿;net.core.somaxconn调太高,可能耗尽内存。解决办法一是回滚参数,二是用sysctl.conf的备份恢复重启前的状态。你在改动前养成先备份/etc/sysctl.conf的习惯,这里就能少掉头发。

另一个容易踩的坑是,参数在/proc/sys下临时修改后,重启会恢复默认。所以临时调参验证有效后,一定要记得写入/etc/sysctl.conf持久化,两者都做了才算完整。

5.4 问题排查速查表

现象排查命令常见原因处理方向
负载高但CPU低iostat -x 1 3磁盘IO排队找IO大户,换盘或限流
内存显示占用高free -h看available页缓存被算作used关注available,必要时调swappiness
大量failed passwordtail /var/log/secure被爆破改端口、密钥登录、fail2ban
服务报too many open filesulimit -n文件描述符限制改limits.conf和systemd配置
系统卡顿且wa高vmstat 1 5IO等待严重检查磁盘状态和队列长度
有用户异常登录last -20账号被入侵锁账号、查登录来源、改密码

这张表是我现在处理问题时的默认起点。遇到问题先看现象属于哪一类,再从对应方向深入,效率比逐个命令乱试高得多。

最后再分享一个经验:做性能优化和安全加固,最难的不是掌握命令,而是养成"先观察、再动手、小步改、留记录"的习惯。第18天这个阶段,正是把这些习惯内化到肌肉记忆里的好时候。你可以先找一台非生产环境的测试机,把文章里的命令完整跑一遍,对着输出理解每个指标的含义,再开始改配置。踩过几次坑之后你会发现,所谓运维实战能力,其实就是这些基础动作在重复中积累出来的判断力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 14:55:28

React Native鸿蒙适配实战:待办列表组件从白屏到流畅运行

最近把一个 React Native 的待办事项列表组件完整跑到了鸿蒙设备上,整个过程比预想中曲折不少,但收获也很大。待办事项列表看起来是入门级 demo,实际上它是移动端高频交互场景的一个典型缩影:既要有增删改查这种基础数据操作&…

作者头像 李华
网站建设 2026/10/10 14:55:01

gvim命令大全实战指南:从模式寄存器到批量替换与避坑

简介:这份gvim命令大全面向Vim/gvim初学者与需要快速查阅快捷键的开发者,系统整理了图形化Vim环境下的常用操作指令,帮助解决编辑效率低、命令记不牢的问题。资源包内共1个doc文档,约90KB,以纯文本形式罗列命令与简要说…

作者头像 李华
网站建设 2026/10/10 14:51:55

Spring Boot + Vue前后端分离律所案件管理系统开发全解析

1. 项目概述与核心需求拆解1.1 律所管理系统到底解决了什么问题我先把这个项目放在一个真实的场景里聊一聊。你在一个律师事务所里,日常办公最头疼的是什么?不是打官司,而是案件信息的流转和管理。一个律师手头同时跟进七八个案子&#xff0c…

作者头像 李华
网站建设 2026/10/10 14:51:13

手写体、超大工程图与科学图表:TeleOCR 的适用边界实测报告

手写体、超大工程图与科学图表:TeleOCR 的适用边界实测报告 【免费下载链接】TeleOCR 项目地址: https://ai.gitcode.com/XingChen-AGI/TeleOCR TeleOCR 的社区热度几乎全部由榜单数字点燃:1.2B 参数、OmniDocBench v1.6 综合 96.87 分登顶、Wil…

作者头像 李华
网站建设 2026/10/10 14:50:57

基于Java与Vue的智慧停车反向寻车:多源融合定位与语义引导实践

简介:这份资源面向具备Java与Vue基础、熟悉Spring Boot与MySQL的开发者及计算机专业高年级学生,针对地下停车场寻车困难、信号弱、定位不准等痛点,给出智慧停车反向寻车语义引导与弱信号定位平台的完整项目实例。内容覆盖停车场数字孪生建模、…

作者头像 李华
网站建设 2026/10/10 14:50:25

Spark on YARN从零配置实战:版本选型、内存参数与避坑指南

去年接了一个数据平台的活,团队里几个新同学上来就被 Spark 配置折腾得够呛。明明看文档都会,一上集群就各种ClassNotFoundException、Container exited、物理内存超限。我自己的经验是,Spark 的配置说难不难,但它藏在一堆配置文件…

作者头像 李华