蓝绿发布中必须在构建阶段完成 composer install 并打包,禁止现场执行:因现场安装会触发 PHP 运行时状态变更、扩展冲突、autoload 重建及开发依赖混入,导致切流瞬间出现 500 错误或请求失败。

蓝绿发布中不能在生产机上直接运行 composer install,必须在构建阶段完成依赖安装并打包 —— 否则切换瞬间会因文件写入、autoload 重建或扩展加载冲突导致 500 错误或请求失败。
为什么不能在绿环境里现场执行 composer install
现场安装会触发 PHP 运行时状态变更,而蓝绿切换要求“新环境完全就绪后才导流”。常见问题包括:
-
vendor/中二进制扩展(如ext-redis、ext-gd)与当前 PHP 版本/编译参数强绑定,从蓝环境拷贝过来可能报Module 'xxx' already loaded或undefined symbol - 未加
--no-dev会把phpunit、phpstan等开发依赖装进生产环境,增大攻击面且引发自动加载冲突(例如两个版本的symfony/console同时存在) - 不加
--optimize-autoloader会使 PSR-4 映射走动态解析,QPS 下降约 8–12%(实测 Laravel 9 + PHP 8.2) -
COMPOSER_PLATFORM_CHECK、opcache.enable等隐式变量影响安装结果,跨环境复用等于跳过校验
CI 构建阶段必须执行的 Composer 命令
所有依赖必须在 CI 流水线中、与目标生产环境一致的 PHP 版本下完成安装。关键命令只有一条,但参数缺一不可:
composer install --no-dev --prefer-dist --optimize-autoloader --apcu-autoloader
说明:
-
--no-dev:排除开发依赖,避免污染生产环境 -
--prefer-dist:优先下载压缩包而非 git clone,减少网络和权限风险 -
--optimize-autoloader:生成静态 classmap,加速自动加载 -
--apcu-autoloader:仅当 APCu 已启用时生效,否则自动退化为普通优化模式,无需条件判断
注意:composer.lock 必须由 CI 构建机生成并提交,不能依赖本地开发机生成的锁文件 —— 因平台差异(如 ext-intl 是否启用)会导致解析结果不同。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
部署包结构与 vendor 目录隔离
每个蓝/绿环境必须拥有独立的 vendor 目录,禁止共享或软链接复用。典型部署路径结构如下:
/var/www/app-blue/ ├── current → releases/20260601-1023 ├── releases/ │ ├── 20260601-1023/ # 含完整 vendor/、bootstrap/cache/、public/ │ └── 20260521-1422/ ├── shared/ │ ├── .env │ ├── storage/ │ └── uploads/ # 指向 S3 或 NFS,不随版本切换
要点:
- 每次部署生成带时间戳的
releases/xxxx/目录,内含完整vendor/和已缓存的配置/视图 -
shared/目录存放跨版本状态资源,新 release 中通过ln -sf建立软链,而非复制 - 切换时只改
current软链指向,确保原子性;切完再重启 queue worker、WebSocket 等长进程
流量切换前必须验证的三项内容
绿环境就绪 ≠ 可以切流。以下三件事没做完,切流就是赌运气:
- HTTP 健康检查端点返回
200 OK,且响应体含"status":"ready"类明确标识(不能只看状态码) - 关键业务接口(如登录、下单)在绿环境手工或自动化调用成功,确认数据库兼容层未抛异常
- 日志中无
PHP Warning: Module '.*' already loaded、Class not found或Undefined index类错误(建议用grep -i "warning\|error" /var/log/php-fpm/www-error.log | tail -20快速筛查)
最容易被忽略的是:数据库迁移必须在切流前完成兼容性验证(比如新增字段不能让旧版代码 crash),或安排在切流后、蓝环境下线前的窗口期执行 —— 否则蓝环境可能因 schema 不匹配而突然失效。

















