上线验收这事儿,其实最怕的就是把标准定低了。我上个月就遇到一个做教育投放的团队,把斗篷系统迁到新服务器,流量结构看着特别简单:日均一千二三的点击,七成移动端,页面版本就两个。环境装完跑通就上线了,结果第三天高峰期开始周期性502。复盘的时候发现PHP-FPM进程池用的是安装包默认值,pm.max_children只有5,稍微来点并发请求队列就满了。说白了,独立部署的验证基准不应该是“装完能打开”,得是“这套配置能不能在你自己的流量结构里稳定跑下去”。所以这篇不打算讲怎么装,就围绕部署环境上线前、运行中、异常后三个阶段的检查重点,把每条检查项对应的失败代价讲清楚。
上线前:用三类约束倒推验证项
部署完成后按下启动键之前,先别急着发版。这里容易搞混,上线前的核验逻辑要从三类具体约束出发:流量结构、部署环境、验收要求,不是凭感觉查一查就完事。
流量结构决定进程池参数。 如果你的流量七成来自广告点击,请求会在投放时段内呈现明显波峰。我的习惯是先估算单秒请求峰值,再反推PHP-FPM的pm参数。比如日均两千点击、投放集中在晚上八点到十点,可以粗略把单秒峰值估到8到12个请求。上面那个案例里pm.max_children=5显然不够,合理做法是设为估算峰值的两倍左右,并让pm.start_servers处于中间水位。这里不只看PHP,Nginx的worker_processes也要和CPU核数匹配,避免进程上下文切换吃掉响应预算。这个点很多人会漏掉。
部署环境决定组件版本边界。 如果服务器是CentOS系而本地测试环境是Ubuntu,PHP版本和扩展路径都可能不同。务必在目标机器上执行php -m核对关键扩展是否缺失,并用php --ini确认加载的配置文件路径。之前有个团队在本地测得好好的,上生产后分流逻辑全部失效,最后查出来生产环境的opcache.validate_timestamps默认开启而本地关闭,规则文件更新后没有被及时感知。这类“环境差异坑”不靠肉眼查,靠命令核对。真的,别省这一步。
验收要求决定日志采样级别。 如果上线验收标准是“所有请求都能回溯”,那日志必须全量记录,不能开条件采样。否则等你发现某个访客被分错页面版本,去翻日志时只看到一条采样留下的空档,排障无从下手。全量日志会占磁盘,但部署初期的日志量相对可控,等稳定运行后再调整采样率也不迟。
运行中:盯住三类“缓慢漂移”
系统上线后不会立刻坏掉,而是先出现缓慢的性能漂移。运行中的检查重点是那些会累积的问题,等它自己暴露就晚了。第一类是进程池饱和度。 可以写一个简短的定时采集脚本,每分钟记录一次php-fpm的活跃进程数和队列长度。如果活跃进程数长时间贴着max_children,说明请求处理能力已经触顶,接下来就是延迟升高和502。我的习惯是不要等到告警才处理,活跃进程占比持续高于七成就要考虑调参或扩展进程数。这个阈值不是拍脑袋,是实际跑出来的经验值。
第二类是缓存与版本一致性。 斗篷系统的分流规则经常需要热更新,但Nginx、PHP、以及自定义规则缓存之间如果失效节奏不一致,就会出现部分请求命中旧规则、部分命中新规则的情况。运行中要定期用一个固定测试UA去请求同一URL,确认返回的页面版本稳定。出现跳变时优先排查分流节点缓存不一,再检查规则文件更新时间戳。顺序别搞反了。
第三类是磁盘与日志增长。 全量日志在投放高峰期增长很快,尤其是移动端流量占比高时,每个请求带的设备信息字段更长。建议给日志目录设置独立挂载点,并配置logrotate按天切割、保留最近7天。磁盘写满会让Nginx直接拒绝新日志写入,进而拖慢响应链路。这事儿我见过好几次,都是磁盘满了才想起来看。
异常后:按回滚点顺序恢复
异常发生后最容易犯的错是“先改配置试试看”。在没有明确回滚点的情况下乱调,可能把原本的小故障扩大成整站不可用。先停下来,按顺序走。第一回滚点是规则库。 如果分流决策出现大面积错误,先确认规则库是否刚刚更新过。把规则库回退到上一个稳定版本,比去改Nginx配置安全得多。回退动作本身应该在部署时预留好:保留每个规则文件的备份,并记录生效时间。这个动作平时不显眼,出了事才知道多重要。
第二回滚点是进程池参数。 如果502集中在投放高峰时段,而日志里没有明显的规则错配,优先检查进程池是否被打满。此时把pm.max_children调高一档并平滑重启php-fpm,通常能快速止血。但这里有个前提:调高进程数会占用更多内存,所以要确认服务器剩余内存足够,否则会诱发OOM杀进程。别为了止血把内存打爆,那就更麻烦了。
第三回滚点是版本绑定条件。 如果只有部分访客出现版本错乱,且集中在某个UA或设备类型上,要回到请求指纹版本错配,检查UA解析逻辑和缓存键的拼接方式。这种异常往往是上线前没有覆盖到的边界条件,回退到上一个配置版本后,再补充测试样例。测试样例得跟上,不然回退了下次还会踩。
小结
部署环境自检的核心不是“有没有装好”,而是“能不能在真实流量结构里稳定运行”。上线前用流量峰值倒推进程池参数,运行中盯住进程池饱和度和缓存一致性,异常后按规则库、进程池、版本绑定条件的顺序回退。每一步都对应着一类真实发生过的线上故障,把这些检查项落进日常运维习惯里,比事后看告警被动响应要省心得多。
常见问题
php-fpm进程池参数怎么设置比较合适?
这个要看你的流量峰值,不能照搬默认值。先估算投放时段的单秒峰值请求数,把pm.max_children设为峰值的两倍左右,再让pm.start_servers落在中间水位,最后观察活跃进程占比来微调。
运行中经常出现页面版本跳变,是哪里出了问题?
大概率是缓存更新节奏不一致。Nginx缓存、PHP缓存、自定义规则缓存各自有失效时间,如果更新不同步,同一访客可能先命中旧规则再命中新规则。建议固定一个测试UA定期请求同一URL,看返回版本是否稳定。
异常回退时应该先改哪里?
先回退规则库,再动进程池参数,最后才去查版本绑定条件。这个顺序的底层逻辑是:规则库回退成本最低、影响面最可控;进程池参数调整需要平滑重启;版本绑定条件排查最耗时,适合放在最后。顺带说一句,我一般会在部署时就把规则文件备份好,回退就是一条命令的事。
延伸阅读
环境自检做完之后,跳转链路本身的选型也会直接影响稳定性,推荐补一下页面跳转技术的几种实现方式对比,对理解状态码竞态和延迟取舍有帮助。