如何排查AWS Ubuntu Linux服务器上CPU占满的异常进程?
排查AWS Linux服务器CPU飙升至100%的问题
我在AWS上运行一台搭载Apache和MySQL的Linux服务器,系统信息如下:
Linux servername 5.15.0-1022-aws #26-Ubuntu SMP Thu Oct 13 12:59:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
每隔几天,AWS控制台会显示CPU飙升至100%,此时无法通过SSH连接服务器,服务器虽能ping通,但无法建立其他连接(比如HTTPS)。
我尝试用无限循环每10秒记录CPU负载TOP10进程到proc.txt,命令如下:
ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10 >> proc.txt
但记录里单个进程CPU峰值最高只有15%。根据AWS控制台,CPU峰值持续超过10秒,理论上应该能捕捉到异常,但目前只能强制重启服务器恢复。
请问有什么排查方法?
更新:
以下是PHP查询MySQL的代码:
<?php function DBquery($qry) { $mysqli = new mysqli("localhost", "<mysql-userid>", "<mysql-password>", "<DBname>"); $results = $mysqli->query($qry); $mysqli->close(); return $results; } <HTML> <HEAD> <TITLE>Results</TITLE> </HEAD> <BODY> Here are your results:<p> <table> <?php $results = DBquery("SELECT team,venue,datetime FROM tbl_schedule WHERE venue='".$_POST['venue'].';"); while ($row=$results->fetch_array()) { echo "<tr><td>".$row['datetime'].'</td><td>'.$row['team'].' </td><td>'.$row['venue'].'</td></tr>'; } ?> </table> </BODY> </HTML>
排查步骤
1. 修正进程监控的局限性
当前ps命令只取TOP10进程,但CPU飙升可能是大量低CPU进程累加导致的(比如几百个Apache子进程各占5% CPU,总和就到100%)。调整监控方案:
- 记录所有进程的CPU使用,而非仅TOP10:
ps -eo pcpu,pid,user,args >> proc_full.txt - 同时记录系统整体负载和CPU核心统计:
date >> cpu_stats.txt && mpstat -P ALL >> cpu_stats.txt && top -b -n 1 >> cpu_stats.txtmpstat可查看单个CPU核心的占用情况,排除单核心被占满的可能;top -b -n1能一次性输出完整的系统进程状态。
2. 修复PHP代码中的致命问题
从更新的代码看,存在两个核心问题直接导致资源耗尽风险:
- SQL注入漏洞:直接拼接
$_POST['venue']到SQL语句,攻击者可构造恶意输入执行高负载查询,甚至耗尽数据库资源。 - 频繁创建销毁数据库连接:每次查询都新建并关闭mysqli连接,高并发下会产生大量TCP连接开销,拖垮服务器。
修复后的代码:
<?php // 复用数据库连接,避免频繁创建销毁 $mysqli = new mysqli("localhost", "<mysql-userid>", "<mysql-password>", "<DBname>"); if ($mysqli->connect_error) { die("数据库连接失败: " . $mysqli->connect_error); } function DBquery($mysqli, $qry, $params = []) { // 使用预处理语句防止SQL注入 $stmt = $mysqli->prepare($qry); if (!$stmt) { die("SQL预处理失败: " . $mysqli->error); } if (!empty($params)) { $types = str_repeat('s', count($params)); // 字段为字符串类型,可根据实际调整 $stmt->bind_param($types, ...$params); } $stmt->execute(); $results = $stmt->get_result(); $stmt->close(); return $results; } ?> <HTML> <HEAD> <TITLE>Results</TITLE> </HEAD> <BODY> Here are your results:<p> <table> <?php if (isset($_POST['venue'])) { $venue = $_POST['venue']; $results = DBquery($mysqli, "SELECT team,venue,datetime FROM tbl_schedule WHERE venue=?", [$venue]); while ($row=$results->fetch_array()) { echo "<tr><td>".$row['datetime'].'</td><td>'.$row['team'].' </td><td>'.$row['venue'].'</td></tr>'; } $results->close(); } $mysqli->close(); ?> </table> </BODY> </HTML>
3. 分析服务与系统日志
- Apache日志:检查
/var/log/apache2/access.log和error.log,看高CPU时段是否有大量异常请求(高频访问、恶意扫描、大文件下载)。 - MySQL日志:开启慢查询日志,记录耗时超过2秒的SQL:
在/etc/mysql/my.cnf中添加:
重启MySQL后,查看慢日志中的耗时查询,给slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2venue字段添加索引优化查询性能。 - 系统内核日志:检查
/var/log/syslog或执行dmesg,排查是否有CPU软锁、内存不足(OOM)、磁盘IO异常等信息。
4. 监控内存与磁盘IO
CPU飙升时无法SSH,大概率是内存耗尽导致swap频繁读写,进而拖垮CPU。添加以下监控:
- 记录内存与swap使用:
date >> mem_stats.txt && free -h >> mem_stats.txt && vmstat 1 5 >> mem_stats.txt - 监控磁盘IO状态:
iostat -x 1 5 >> disk_stats.txt
5. 利用AWS自带工具
- 查看CloudWatch细分指标:比如
CPUUser、CPUSystem、CPUIowait,判断是用户进程、系统进程还是IO等待导致的CPU飙升。 - 启用Session Manager:即使SSH无法连接,也能通过AWS Systems Manager的Session Manager登录服务器,实时排查故障。
内容的提问来源于stack exchange,提问作者simon
相关产品推荐
相关产品推荐

