You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何排查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.txt
    
    mpstat可查看单个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中添加:
    slow_query_log = 1
    slow_query_log_file = /var/log/mysql/slow.log
    long_query_time = 2
    
    重启MySQL后,查看慢日志中的耗时查询,给venue字段添加索引优化查询性能。
  • 系统内核日志:检查/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:00:57