记一次宕机优化全记录:8H8G 服务器从 99% 内存到 29% 的 1 小时自救

早上刚传完几个官网的新 banner,后台页面就卡在加载圈里不动了 —— 弹窗提示 “连接超时” 的时候,我甚至有点懵:8 核 8G 的服务器,跑 13 个小网站而已,怎么会拉爆?

强制重启后登宝塔面板,内存条直接红到顶,一看进程列表:PHP-FPM 像撒了欢的小孩占了半壁江山,MySQL 的缓存配置跟闹着玩似的。合着不是硬件不够,是默认配置在 “帮倒忙”。

花了 1 小时把这些 “冗余” 挨个捋顺,现在内存稳在 29%,服务器安静得像没开机。索性把过程拆成步骤写下来,省得下次又被这些 “隐形吃内存怪” 偷袭。

一、先搞懂:我的内存是被谁吃了?

宕机后别着急调配置,先定位 “元凶”—— 打开宝塔面板「监控」页,或用 SSH 敲top(按 M 键按内存排序),我当时看到的是:

  • PHP-FPM:59 个进程,单个占 20MB+,总占用超 1G;
  • MySQL:默认配置下,缓存区没开满,但连接数飙高;
  • 静态资源:图片、CSS 每次请求都要重新加载,反复触发 PHP/MySQL。

二、第一步:捏爆 PHP-FPM 这个 “内存大头”(宝塔可视化操作)

PHP 是 WordPress 的 “动力源”,但默认进程数太 “慷慨”,得按服务器配置砍:

1. 调整进程数(所有 PHP 版本通用)

进入宝塔「软件商店→已安装→对应 PHP(比如 7.4)→性能调整」:

  • max_children(最大子进程):从 59/100 改成25(8G 内存建议 20-30);
  • start_servers(起始进程):从 5/10 改成8(服务启动时初始进程数);
  • min_spare_servers(最小空闲进程):保持5
  • max_spare_servers(最大空闲进程):从 11/30 改成12

2. 缩小组件内存限制

切换到「配置修改」标签,找到 memory_limit

  • 从 256M 改成128M(WordPress 跑文章 / 后台足够用)。

3. 额外优化(针对老版本 PHP)

比如 PHP-5.6:

  • max_execution_time(脚本运行时间)从 300 秒改成60 秒(避免慢脚本占内存);
  • 关闭display_errors(避免泄露站点信息)。

三、第二步:给 MySQL “合理分配钱包”

MySQL 默认配置是 “大锅饭”,得按 8G 内存精准调:

进入宝塔「软件商店→已安装→MySQL→性能调整」:

  • innodb_buffer_pool_size(核心缓存区):从 512M 改成2048M(8G 内存的 1/4,这是提升性能的关键);
  • max_connections(最大连接数):从 500 改成200(小站点用不上这么多);
  • sort_buffer_size/read_buffer_size:从 2048KB 改成512KB(单个连接的缓存不用太大);
  • 保持table_open_cache(512)、thread_cache_size(64)不变(已适配 8G 内存)。

四、第三步:给静态资源 “发长期居留证”(每个 WordPress 站都要做)

静态资源(图、CSS、JS)是 “重复请求大户”,缓存能直接让它们不打扰 PHP/MySQL:

1. 配置站点缓存

进入宝塔「网站→对应站点→缓存」:

  • 点击「添加」,依次设置:
    • 缓存后缀 1:gif,jpg,jpeg,png,bmp,swf,webp,ico,svg → 缓存时间30 天
    • 缓存后缀 2:js,css → 缓存时间7 天

2. 配置 WordPress 通用伪静态(Nginx)

进入「网站→对应站点→伪静态」,粘贴以下规则(直接用):

# 核心路由规则 
location / 
{
 try_files $uri $uri/ /index.php?$args;
 }

 # 后台斜杠重定向 
rewrite /wp-admin$ $scheme://$host$uri/ permanent; 

# 禁止缓存后台/插件目录(避免缓存冲突) 
location ~* /(wp-admin|wp-includes|wp-content/plugins)/ {
 expires -1;
 add_header Cache-Control "no-store, no-cache, must-revalidate"; }

# 优化附件访问(直接返回静态文件) 
location ~* ^/wp-content/uploads/ {
 try_files $uri $uri/ =404;
 expires 30d;
 add_header Cache-Control "public, max-age=2592000";
 }

五、最后一步:加个 “自动清内存” 的定时任务

宝塔「计划任务→添加任务」:

  • 任务类型:Shell 脚本
  • 脚本内容:sync && echo 3 > /proc/sys/vm/drop_caches
  • 执行周期:每小时一次(自动清理系统缓存)。

六、优化后效果对比

指标优化前优化后
内存使用率 90%+(爆红)29%(稳定)
PHP 进程数 59 个25 个内
服务器负载 高(卡顿)10%(流畅)

七、30 秒排查 “内存异常进程” 的方法

如果你的服务器突然变卡,不用等宕机,先按这两步找 “吃内存的家伙”:

方法 1:宝塔面板可视化查看(小白友好)

  1. 打开宝塔面板→左侧「监控」→切换到「进程」标签;
  2. 按 “内存” 列排序,一眼就能看到占比最高的进程(比如我当时的 PHP-FPM、MySQL);
  3. 若某进程占比超 10% 且不是核心服务(比如陌生的后台进程),可以点「结束进程」临时释放。

方法 2:SSH 命令行精准定位(更高效)

登录服务器后,敲这 2 条命令:

1.查看实时内存占用

    top

    (按 M 键按内存排序,按 P 键按 CPU 排序,q 键退出)

    2.查看内存占用 Top5 的进程

    ps aux --sort=-%mem | head -6

    (输出结果里,%mem 列就是内存占比,COMMAND 列是进程名)

    比如我当时的输出里,php-fpm 占了 7 个进程,每个占 1%+,加起来直接吃掉 10% 内存 —— 这就是 “隐形吃内存怪” 的典型表现。

    写在最后

    其实服务器和生活挺像的:不是东西越多越稳,是该紧的地方紧,该放的地方放。你给冗余进程腾点空,才能装得下真有用的流量。

    说到底,大部分服务器问题都不是 “硬件不够”,而是 “没看住资源”。把这几步排查和优化的方法记下来,下次遇到卡顿不用慌,先找到 “乱吃东西” 的进程,对症下手就好。