一台服务器跑 5 个 WordPress:共用的收益与六个坑-第三维度MokIII

场景

一台 2 核 4G、5M 带宽的云服务器,跑 5 个 WordPress 站点:

  • 共用一个 PHP-FPM 池;
  • 共用一个 Redis(对象缓存);
  • 共用一个 nginx;
  • 数据库全部外置到独立云数据库。

这台机器的资源利用率很高,成本也低,但"共用"意味着它们会互相影响。下面是我实际遇到的坑和取舍。

一、为什么值得共用

  • 内存和 CPU 利用率高:小站的流量波峰不重叠,共用一份 PHP-FPM 池能显著提高利用率;
  • 运维成本低:升级 PHP、改 nginx 规则、加防火墙,都是一次操作覆盖所有站;
  • 成本低:这是最直接的——一台机器 vs 五台机器。

二、坑 1:PHP-FPM 池是"共享额度",没有隔离

pm.max_children 是整个池的上限,不是每个站一份。

后果:一个站被刷,其他四个站一起排队。表现是"我另一个好好的站怎么突然打不开了"。

缓解办法:

  1. 把 max_children 给足(按内存反推,见另一篇);
  2. 开着 slowlog,出事时能立刻定位是哪个站的什么请求在拖后腿;
  3. 如果某个站明显更重(流量大或插件臃肿),给它单独开一个池——代价是多一份内存开销。

三、坑 2:Redis 共用必须做 key 隔离

同一个 Redis 实例、同一个 db,如果几个站不区分前缀,站点之间会互相读到对方缓存的对象。

症状非常隐蔽:偶尔显示别站的内容、选项莫名其妙错乱、菜单串台——而且刷新一下又好了,极难复现。

解法是每个站加一行常量(写自己的域名):

define( 'WP_CACHE_KEY_SALT', 'https://www.example.com' );

这一行让每个站的缓存 key 带上独立前缀,共用实例也互不干扰。

四、坑 3:flushdb 会清掉所有站

Redis 的 FLUSHDB 不分前缀——你只想清自己这一个站,结果五个站的缓存全没了。

多站共用时,清缓存的正确姿势是:

  • 用插件面板里的「清空对象缓存」(它按当前站的前缀删);
  • 或者自己按前缀批量删 key;
  • 不要在命令行随手敲 flushdb。

另外,Redis 一定要设上限(maxmemory + allkeys-lru),否则某个站的缓存膨胀会把整实例吃满,五个站一起受影响。

五、坑 4:opcache 也是共用的

opcache 的缓存按文件路径区分,所以几个站之间天然隔离,不会串。

但 max_accelerated_files(默认 10000)要按所有站的文件总数来给——文件数不够时超出的部分静默不缓存,你只会觉得"加速效果没预想的好",很难想到是这个值。

六、坑 5:一个站的错误配置会拖垮全部

举个真实例子:某个站开了个插件,用 Imagick 处理大图,单个请求就吃掉几百 MB。

在共用池的情况下,这种请求会同时挤占所有站的 worker 额度。所以:

  • FPM 池里不要把 memory_limit 压得很低(会先挂掉图片处理,反而制造 500);
  • 内存风险靠 max_children 限并发来控制,而不是靠压单进程上限;
  • 这也是我不敢把 max_children 一次提到理论最大值的直接原因。

七、坑 6:日志和备份要按站分开、错峰

  • 日志:nginx 按 $host 分文件(宝塔默认就是 域名.log),否则排障时得在几万行里翻;
  • 备份:五个站的备份如果都设在凌晨同一时刻,会同时打满磁盘 IO。错开十几分钟就有明显改善。

八、什么时候不该共用

共用不是无脑选择。出现下面任一情况,就该考虑把某个站分出去:

  • 流量规模差距大:一个站占了 80% 的资源,其他站成了"受害者";
  • 重要性不同:核心业务站不该和实验站共用池,前者会被后者拖累;
  • 参数需求冲突:某个站需要特殊的 PHP 扩展、特别的 memory_limit、或者要单独调 PHP 版本;
  • 安全边界:不同客户/不同信任级别的站,共用同一进程池在理论上存在越权面。

九、我实际盯的几件事

pgrep -c -f 'php-fpm: pool www'        # 池的实时并发
grep -c 'reached pm.max_children' /www/server/php/82/var/log/php-fpm.log   # 是否顶到上限
swapon --show                          # swap 是否在持续增长(内存不够的信号)
redis-cli info memory | grep used_memory_human

判断标准很简单:reached 告警不出现、swap 不持续增长、五个站的关键页面都能正常打开——满足这三条,说明这台机器的分配是合适的。


一句话总结:多个站共用一台机器,收益是资源利用率和成本,代价是它们会互相影响。要主动处理的就四件事:FPM 池的共享额度(给足 + slowlog 定位)、Redis 的 key 隔离(别 flushdb)、opcache 的文件数(按总站数给)、以及备份/日志的错峰与分文件。