先看现象。前台开始成片报 502,MySQL 错误日志里全是 Too many connections。程序每个请求新开一个连接,蜘蛛并发一上来就把连接数顶到上限。

排查方向其实有限,先把可能性排一排。应用每个请求新建连接,用完不主动释放。少数情况下是max_connections 只有 150,与 FPM 进程数不匹配。

还有一种情况,慢查询占着连接不放,队列越排越长。

另外,没有连接池,突发并发直接顶穿上限。

第一件事是看当前连接数与上限

mysql -e 'show status like "Threads_connected"; show variables like "max_connections";'

再往下抓出占连接最久的语句

mysql -e 'select id,time,state,info from information_schema.processlist order by time desc limit 10;'

然后把上限调到与进程数匹配并接上连接池

SET GLOBAL max_connections = 500;

给慢查询补索引并设语句超时

手上没有现成的复现脚本,就照着线上请求手工拼了一个。

恢复的判定其实很直接。连接数稳定在两百以内,502 不再出现,蜘蛛抓取成功率回到九成九,慢查询条数同步下降。

调大上限只是缓兵之计,连接泄漏不修,调到一千也会在某个高峰被打满。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189