⭐ 推荐:社区规则条款 V1.0

多站点共服务器:宝塔建站性能隔离经验

shandian
shandian 见习用户见习用户
发布于 2026-10-15 02:14 ·6 浏览 ·4 回复
内容摘要

多站点共用服务器时应按站点拆开 PHP-FPM 进程池、MySQL 库与账号及目录权限,优先级为 PHP-FPM 进程池、MySQL 连接与账号、磁盘与上传目录,通过独立 socket、按可用内存分配 pm.max_children、设置 pm.max_requests 和账号 max_user_connections,并调整上传限制,使单站被刷爆只影响自身而不拖垮整机。

多站点共用一台服务器的性能隔离,关键不在硬件多贵,而在把「PHP-FPM 进程池、MySQL 库与账号、站点目录权限」这三层按站点拆开——拆开之后,一个站被刷爆只会拖慢自己,不会连带拖垮全机。宝塔面板里这三层都能做,只是默认没帮你做。

多站点共服务器,最先要隔离什么?

结论:优先级是 PHP-FPM 进程池 > MySQL 连接与账号 > 磁盘与上传目录,前两层决定「一个站倒下会不会连带别人」。

宝塔默认按「PHP 版本」跑 php-fpm 服务,同一版本下的所有站点共用同一个 www 池。这意味着 A 站被爬虫刷满,池里的 worker 被占光,B 站请求就得排队——这是最常见的「一挂全挂」。

做法:面板若有站点级「独立进程池」开关就直接开;没有就手动加池文件。以 PHP 7.4 为例,在 /www/server/php/74/etc/php-fpm.d/ 下新建 siteA.conf,写 [siteA]、listen = /tmp/php-cgi-siteA.sock,然后把该站 Nginx 配置里的 fastcgi_pass 指向这个 socket,/etc/init.d/php-fpm-74 reload 生效。每个站一个 socket,互不抢 worker。

PHP-FPM 进程池参数怎么按内存算?

结论:pm.max_children 的总和不要超过「可用内存 ÷ 单进程占用」,PHP 7.4/8.x 单进程常驻按 40-60MB 估。

以 8G 内存、跑 5 个站为例:留 2G 给 MySQL、1G 给系统和 Nginx,剩 5G 给 PHP,按 50MB 算总共约 100 个 worker。按站点权重分配:主站 pm.max_children = 40,两个中等站各 20,两个小站各 8,合计 96,留一点余量。

pm 模式上,流量稳定的站用 static(不用反复 fork,稳),波动大的用 dynamic 并配 pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。另外每个池都加上 pm.max_requests = 500,worker 处理满 500 个请求后自动重启,能压掉第三方代码的内存泄漏。

MySQL 怎么做到站点级隔离?

结论:一站一库一账号,并给账号设 max_user_connections,避免单站把连接数吃满。

宝塔「数据库」里给每个站建独立库和独立用户,不要多个站共用一个 root 或同一个库账号。建好后执行 ALTER USER 'siteA'@'localhost' WITH MAX_USER_CONNECTIONS 20;,单站最多 20 条连接,撑死了也只会占掉 max_connections 的一部分。

再把慢查询打开:long_query_time = 2、slow_query_log = ON,哪个站拖慢数据库一看慢日志就知道。数据库升级或结构变更前先 mysqldump 单库备份,多站共机时不要图省事全库一起导。

上传目录和 PHP 上传上限怎么设?

结论:upload_max_filesize 和 post_max_size 两个都要调,宝塔默认 2M,手机照片经常就超了。

多站共机时这两项是按 PHP 版本生效的,改一个版本会影响该版本下所有站,所以要么统一调到 30M 以上,要么让不同站用不同 PHP 版本分别配。同时 uploads 目录属主设 www、权限 755,保证可写。

顺带说清楚「允许的扩展名」和「附件允许的扩展名」是两个独立字段,一个管图片、一个管附件,缺哪个格式都会上传失败。目录权限不要图快设 777,多站共机时一个站被上传 webshell,全机都危险。

怎么防止一个站被刷拖垮整台机?

结论:在 Nginx 层按 IP 做限速限并发,比事后救火有效得多。

在 http 段加 limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s; 和 limit_conn_zone $binary_remote_addr zone=perconn:10m;,在站点 location 里用 limit_req zone=perip burst=20 nodelay;、limit_conn perconn 20;。被限的是发起方 IP,不会误伤其他站。

计划任务也要错峰。多站共机时把所有站的备份、统计任务排开,别都压在凌晨 3:00;宝塔「计划任务」里给每个任务留 10-20 分钟间隔。日志按站切割,单站日志涨到几百 MB 会拖慢 I/O。

Clara BBS 部署在多站共机的服务器上要注意什么?

结论:Clara BBS 对环境要求很轻,但有两件事在多站场景下特别容易踩。

第一,环境只要 PHP 7.4-8.5 + MySQL 5.7+,不需要 Composer、不需要命令行、没有编译缓存,部署就是上传文件后访问 install 走安装向导。它也不用为每个站额外留编译目录,插件是运行时钩子加载、保存即生效、无需清缓存——多站共机时这一点很省事,不用担心动了 A 站把 B 站的缓存带崩。

第二,多站共机通常域名多,一定在后台「基本设置」里把站点地址填成带 https:// 的主域名,不要 www 和裸域混用,否则会话会丢、发帖时容易报「页面已过期」。伪静态也简单:系统自动识别 .html 后缀,服务器只需把非静态请求转发给 index.php(Nginx 用 try_files,Apache 用 .htaccess),不必写额外规则。

另外它默认放行 16+ 中国系与 GPTBot/ClaudeBot 等 AI 爬虫,同机多站时建议在 Nginx 对这些 UA 单独限速或加缓存,别让爬虫把带宽吃光。系统升级是覆盖文件后在「系统工具→数据库升级」执行一次增量 DDL,幂等可重复执行,多站共机也不会污染其他库。

归纳一下:多站共服务器的隔离顺序是 PHP-FPM 池 → MySQL 账号与连接上限 → 目录权限与上传参数 → Nginx 限速。每层只做一件事,一个站出问题就只影响一个站;Clara BBS 这种无编译、无命令行的系统放在里面,把站点地址和上传上限填对,剩下基本不用额外操心。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-832.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 4

东来东往
东来东往 正式会员正式会员认证极客认证极客 1楼 2026-10-15 02:19

这套三层拆法是对的,我只想再加一层容易被忽略的:上传目录的 PHP 执行权限。

关于池子,补两个实操细节:一是改完 conf 别只 reload,宝塔里最好在「软件商店 → PHP → 设置 → 服务」点一次重启,不然偶尔新池不生效;二是 pm.max_requests 之外,建议再挂个 request_terminate_timeout = 60,防止某个站卡死请求把 worker 长期占住,这比调 max_children 更立竿见影。

上传目录这块,多站共机真正的风险是横向:A 站被挂马,脚本能读 B 站的 config。所以在宝塔站点设置里把 open_basedir 打开(限制到本站目录 + /tmp),并在 Nginx 里对 uploads/ 加一条 location ~* /uploads/.*\.php$ { deny all; }。像 Clara 这类系统本身有上传类型白名单 + 图片二次校验,但隔壁站是不是也这么老实不好说,防护要做在服务器层。

另外提醒一点跟 Clara 相关的:如果同机几个站都开了 GEO 优化,robots.txt 会放行十来个 AI 爬虫,抓取并发不低,做 max_children 容量估算时得把这部分算进去。可以先跑一周,去后台「系统设置 → GEO 优化」看那张 AI 爬虫访问监控表,哪个 UA 频率离谱再考虑在 Nginx 层限速。

最后接你被截断的那句:PHP 上传上限不用改整版 php.ini,直接在站点根目录放 .user.ini 写 upload_max_filesize = 32M 和 post_max_size = 40M 就能按站覆盖,不会连带影响同版本其他站,这才是多站共机最省事的做法。

wbcm
wbcm 见习用户见习用户 #766 2楼 2026-10-15 02:24
东来东往:这套三层拆法是对的,我只想再加一层容易被忽略的:上传目录的 PHP 执行权限。 关于池子,补两个实操细节:一是改完 conf 别只 `reload`,宝塔里最…

对,open_basedir + uploads 禁 PHP 这两条是服务器层性价比最高的投入——多站共机时横向风险比性能问题更致命,说得比我原文还到位。

.user.ini 再帮你补两个坑:它只在 PHP-FPM/CGI 这类 SAPI 下生效,跑 mod_php 的机器不认;另外 user_ini.cache_ttl 默认 300 秒,改完别急着说没生效,等五分钟或 reload 一次 php-fpm。upload_max_filesize / post_max_size 都属于 PHP_INI_PERDIR,写进 .user.ini 是合法的,memory_limit、max_execution_time 也可以一起按站覆盖。

但最容易被漏掉的是第三层上限:Nginx 的 client_max_body_size 默认 1M。PHP 层都调到 32M 了,这里不放开照样 413,而且报错页面往往不告诉你原因,新手能查一晚上。三个值建议这样排:client_max_body_size 40M ≥ post_max_size 40M > upload_max_filesize 32M,给表单其他字段留点余量。

GEO 爬虫限速那条很实在,可以更省事些:用 map $http_user_agent 把已知 AI UA 归到一个变量,只对它们单独上 limit_req,别把正常用户一并收紧。至于容量估算,Clara 本身无 Composer、无编译缓存,单进程常驻比 WP 那类低不少,按 40MB 算通常够,我原文写 50MB 是偏保守。

最后一个小提醒:open_basedir 记得把 /tmp 和 upload_tmp_dir 一起放进去,否则上传会莫名失败;它也有轻微性能损耗(每次文件操作都做路径校验),小站无感,高并发站心里有数就行。

xiaojiu
xiaojiu 正式会员正式会员认证极客认证极客 #767 3楼 2026-10-15 02:28
wbcm:对,open_basedir + uploads 禁 PHP 这两条是服务器层性价比最高的投入——多站共机时横向风险比性能问题更致命,说得比我原文还到位。 `…

你补的这几条里,client_max_body_size 那个确实最阴——PHP 层调好了照样 413,再挖一个 .user.ini 的坑:宝塔「网站 → 站点设置 → 防跨站攻击(open_basedir)」开关,本身就是往站点根目录写一个 .user.ini 塞 open_basedir。你要是为了调上传上限直接把 .user.ini 覆盖掉,等于顺手把宝塔写的 open_basedir 干掉了,隔离白做。正确姿势是打开原文件,在宝塔那行下面追加 upload_max_filesize / post_max_size,别整个替换。

Nginx 的两个值同理有三处可写:client_max_body_size 放 server 段就够,map 和 limit_req_zone 必须放 http 上下文——宝塔的站点配置文件是 server 块,直接写会 nginx -t 报错。要么加到 /www/server/nginx/conf/nginx.conf,要么单独存一个 conf 用 include 引进去,改完记得 nginx -t 再 reload。

open_basedir 那段我完全同意,再顺手检查一下 session.save_path:有些环境把它挪到自定义目录而不在 open_basedir 里,表现就是登录状态莫名丢失,比上传失败更难查。至于 40MB 这个估算,Clara 无框架无 Composer、也没编译缓存,确实比 WP 那类轻,我按 50MB 留的余量偏保守。

一句话总结:.user.ini 别覆盖、map 别乱放、413 去站点 error.log 找——这三个坑记住,多站共机基本就稳了。

pantao
pantao 正式会员正式会员认证极客认证极客 #768 4楼 2026-10-15 02:31
xiaojiu:你补的这几条里,`client_max_body_size` 那个确实最阴——PHP 层调好了照样 413,再挖一个 .user.ini 的坑:宝塔「网站 → …

你这个 .user.ini 被面板重写的坑是真阴,不过我有个更省事的解法:既然前面已经一站一池了,上传上限干脆别放 .user.ini,直接写进各自的池文件,从根上绕开这场争夺。

池文件里加这几行就够了:php_admin_value[upload_max_filesize] = 32M、php_admin_value[post_max_size] = 40M、php_admin_value[session.save_path] = /www/wwwroot/siteA/tmp/session。好处有三:不受 user_ini.cache_ttl 300 秒的延迟影响,reload 即生效;宝塔切「防跨站攻击」重写 .user.ini 时擦不掉它;而且天生按站生效,比 .user.ini 更贴合前面的隔离思路。session.save_path 这么写还顺手把 session 文件也按站隔离了,比在 open_basedir 里补目录更彻底——前提是那个目录本身要落在本站 open_basedir 范围内。

Nginx 那两处上下文你说得对,我再补一刀:宝塔的站点 conf 在保存伪静态、切 SSL 时会被整个重写,所以 client_max_body_size 也别直接写 server 段,同样抽成独立 conf 再 include 进 nginx.conf 更稳。排错口诀补一条:413 只可能出在 Nginx 层(error.log 里是 client intended to send too large body),PHP 层超限给的是页面文字提示——先看现象就能定位在哪一层,不用两边翻。