服务器CPU莫名满载时,先别急着优化代码或升级配置,编译一个临时防护脚本,优先排查DDoS和CC攻击,这类恶意流量占据CPU异常排查的相当一部分比例,且最容易遗漏。
很多站长遇到CPU跑满的第一反应是查慢查询、看进程、抠代码细节,忙活半天找不出原因,等日志攒够了才发现,半天前一场小规模攻击早就结束了,与其让业务白扛几小时,不如按这篇文章的顺序自查,全文不给你堆概念,只讲怎么用现有工具把隐藏的攻击挖出来。
服务器CPU莫名满载?先排查这类攻击再说
CPU满载的诱因分两大类:程序自身问题和外部流量攻击,业内专家指出,后者在“莫名满载”场景中的比例远高于预期,尤其是那些规模不大、平时流量平稳的业务站,正常业务量的波动有规律可循,而攻击流量往往呈脉冲状,突然飙升又迅速回落,让你在翻日志时无从下手。
为什么没人访问CPU还是满载
这是个高频困惑,白天有访客时CPU正常,深夜流量低谷反而满载,这本身就指向攻击,攻击者常选流量低峰时段下手,目标是让你在错误的时间段排查,恰好错过攻击窗口,破解方法很简单:直接看实时连接状态,不要只看CPU占用率曲线。
攻击与程序Bug的核心区别
程序出Bug通常有明确触发路径,比如某个接口传了特殊参数、某个定时任务卡死,现场可复现,攻击则呈现来源IP分散、单连接存活时间极短、请求频率异常的特征,如果你发现CPU占用曲线如锯齿般频繁抖动,大概率是外部流量在敲门。
服务器CPU占用100%怎么排查:五步锁定攻击源
排查讲究顺序,别从下往上翻,先看网络层,再回看应用层,下面这套流程能用命令行完成,不需要装额外工具。
第一步:观察连接状态分布
登录服务器,先跑 ss -s 或 netstat -n | awk '{print $6}' | sort | uniq -c | sort -rn 汇总TCP连接状态数量,重点看 SYN_RECV 和 TIME_WAIT 两个数字。SYN_RECV 数量破千

就非常可疑,正常业务几乎不会出现大量半开连接,这是SYN Flood的典型特征。
第二步:按连接数排名找“大客户”
用 netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20 列出连接数最高的前20个IP,如果某个IP的连接数占总量过半,不要犹豫,先用 iptables -I INPUT -s 该IP -j DROP 封掉再继续查,攻击者常用IP池轮换,单IP封禁只是临时止血。
第三步:用tcpdump抓取特征包
连接数看不出来时,直接抓包分析,执行 tcpdump -i eth0 -nn port 80 -c 2000 抓2000个包,保存后分析请求特征,攻击流量的共性是HTTP头不完整、User-Agent重复率极高、GET请求参数固定,正常爬虫虽然UA单一但访问间隔规律,攻击则是同一时刻发起大量并发。
第四步:确认应用层日志时间线
grep "攻击时间段" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c 统计访问日志中每个IP的请求量,如果单IP在一分钟内发出上千次请求,那就是CC攻击没跑了,这一步能区分“攻击”还是“爬虫失控”,后者至少会遵守robots协议或带有正常UA。
第五步:动态追踪,别急着重启
很多人在这一步直接重启服务,其实浪费了最佳取证时间,用 pidstat -p 进程号 1 5 观察进程CPU占用是否周期波动,如果每几秒规律跳变一次,多为攻击脚本的循环间隔,截图留存记录后,再重启服务不迟。
Web服务遭遇CC攻击的症状与自检方法
CC攻击比DDoS更隐蔽,它不消耗带宽,而是用大量看似合法的请求拖垮应用层,同样是CPU满载,DDoS会同步占用带宽和连接数,CC则往往带宽正常、连接数正常、但CPU和内存居高不下。
CC攻击的三大信号
- CPU占用高但带宽使用率低于30%,说明请求体积小、频率高,负载集中在应用处理。
- 日志中大量200状态码但对应页面无实际访客价值,比如攻击者反复请求某个动态接口或搜索页。
- 相同UA或相同Referer在短时间内集中出现

,攻击脚本常伪装成搜索引擎UA来绕过简单过滤。
怎么判断是CC还是正常突发流量
把最近一小时的完整访问日志按分钟切片,awk '{print $4}' access.log | cut -c14-15 | sort | uniq -c 看每分钟请求数分布,正常突发流量是连续增长后再连续下降,CC攻击则是请求数突然到峰值,结束也干脆利落,流量进出像拉电闸一样突兀,基本就是攻击。
验证攻击源的技巧:更换端口测试
临时将Web服务端口从80改到8080,执行 sed -i 's/listen 80/listen 8080/' /etc/nginx/conf.d/default.conf 后重载配置,如果CPU占用率立即下降一大半,说明攻击者只锁定默认端口,这种攻击针对性弱、很容易防护,如果改端口后CPU依旧满载,攻击者做了端口探测,性质就完全不同了。
攻击类型清晰后,用最快方式止损
熟悉常见攻击类型能帮你缩短排查时间,但别沉迷分类,重点在落地防御,蠕虫病毒、挖矿木马、慢速连接攻击这几类需要单独应对,处理思路与CC攻击完全两套逻辑。
遇到DDoS时的即时操作
除非你的服务器在硬防后面,否则单机抗DDoS的能力很有限,先在防火墙上禁掉异常协议包:
iptables -A INPUT -p tcp --syn -m limit --limit 5/s -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP
这条规则把每秒新增SYN请求限制在5个,超出即丢弃。服务体验会下降,但CPU能保住,之后联系机房或云厂商开启流量清洗,数据中心级别的防护才是正解,多数云平台自带防DDoS基础包,只是需要你提前在控制台确认是否已开启。
应对CC攻击的应急策略
先加Nginx层限制,让Nginx挡在前面消耗最小资源拒绝攻击请求:
limit_req_zone $binary_remote_addr zone=cc:10m rate=10r/s;
server {
location / {
limit_req zone=cc burst=20 nodelay;
proxy_pass http://backend;
}
}
这段配置限制每个IP每秒最多10个请求,效果立竿见影,但攻击者如果用大范围IP池就没太大用处,需要结合上文的日志分析封IP段。

服务器CPU满载在纯内网环境下的非攻击因素
如果上面全套排查找不到攻击痕迹,内网环境还需要关注三个被忽视的病根:数据库连接数泄漏、日志写入循环、Swap分区颠簸,特别是云服务器上跑Java或Python应用,连接池配置不当导致线程等待是CPU虚高的隐性因素,用 jstack 进程号 抓线程快照,看到大量 WAITING 状态线程就知道问题出在哪了。
关于服务器被攻击后CPU满载,你需要知道的三个问题
攻击停止后CPU为什么还是满的
攻击可能给系统留下了“后遗症”,最常见的是攻击期间积累的大量TIME_WAIT连接未清理,在 /etc/sysctl.conf 里加两行再执行 sysctl -p 能快速缓解:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
另一个可能是系统负载平均值还没降下来,top 里显示的load average是过去1/5/15分钟的平均值,先观察几分钟再下结论。
免费防护和收费防护的本质区别在哪
免费方案靠手动封IP和规则配置,适合攻击频率不高的中小站点,收费防护是流量调度到高防节点后再回源,防御带宽从几百G起步,攻击再猛也不直接打在源站上,规模低于5Gbps的小打小闹,免费方案完全够用。
被攻击后要不要立刻升级CPU配置
不要,如果攻击流量打的是应用层,升核等于给攻击者加火力,CPU越强处理请求越快,攻击消耗你的资源也越有效率,省下升级的钱,先接入CDN或高防IP把源站藏起来,再考虑加配置不迟,CPU密集型业务的日常扩展是另一回事,与攻击场景无关。
排查CPU满载这种事,顺序比技巧重要,先怀疑网络层,再分析应用层,最后才轮到代码性能,服务器CPU莫名满载的常见原因优先级始终是:DDoS/CC攻击,慢连接耗尽连接池,应用程序Bug,硬件故障,按这个顺序走一遍,多数问题在那个“排查这类攻击”的环节就能画上句号。