PHP 怎么PHP 原子部署

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 原子部署

  1. 使用符号链接(Symbolic Link)切换
  2. 使用 OPcache 配合 APCu 预加载
  3. 使用部署工具(如 Deployer、Envoy)
  4. 蓝绿部署 / 金丝雀发布(容器化场景)
  5. 数据库迁移的原子性
  6. 推荐方案

在 PHP 项目的原子部署(Atomic Deployment)中,核心目标是在用户无感知的前提下完成版本更新,避免出现“部分文件已更新、部分文件未更新”导致的代码不一致问题,下面是几种常见的 PHP 原子部署实现方式:


使用符号链接(Symbolic Link)切换

这是最经典的原子部署方式,适用于绝大多数 PHP 项目(如 Laravel、ThinkPHP、原生项目等)。

结构示例

/var/www/
├── releases/
│   ├── 20240501_v1.0/
│   │   ├── app/
│   │   ├── vendor/
│   │   └── index.php
│   ├── 20240502_v1.1/
│   │   ├── app/
│   │   ├── vendor/
│   │   └── index.php
│   └── 20240503_v1.2/
│       ├── app/
│       ├── vendor/
│       └── index.php
└── current -> /var/www/releases/20240503_v1.2/

部署步骤

  1. 准备新版本
    将代码部署到新的目录,如 releases/20240504_v1.3/

  2. 安装依赖、构建
    在该目录内执行 composer installnpm build 等操作(不影响当前运行版本)

  3. 切换符号链接

    ln -sfn /var/www/releases/20240504_v1.3 /var/www/current
  4. 重启 PHP-FPM(可选)
    有些框架(如 Laravel)需要清除 OPcache,可用 opcache_reset() 或执行:

    kill -USR2 $(pgrep php-fpm)

优势

  • 切换瞬间完成,无停机时间
  • 用户请求不会看到「半更新」状态

注意

  • 共享目录如 storage/uploads/ 建议放在符号链接之外,避免被版本覆盖
  • 配置文件参数(如 .env)也建议外挂

使用 OPcache 配合 APCu 预加载

变化但 OPcache 未刷新,PHP 仍会执行旧代码,需要确保 OPcache 在部署后及时失效

实现方式

在部署脚本最末尾执行:

<?php
if (function_exists('opcache_reset')) {
    opcache_reset();
}

或通过 Nginx/Apache 访问一个清理脚本:

curl -s http://example.com/clear-cache.php

适合

  • 单服务器或少量服务器
  • 不需要零停机

不适合

  • 多服务器集群(需要逐台清理,有短暂不一致风险)

使用部署工具(如 Deployer、Envoy)

这些工具封装了原子部署的逻辑,开箱即用。

示例(Deployer)

host('prod')
    ->set('deploy_path', '/var/www/project')
    ->set('repository', 'git@github.com:user/project.git');
task('deploy', [
    'deploy:prepare',
    'deploy:vendors',   // composer install
    'deploy:symlink',   // ln -sfn 切换
    'deploy:cleanup',   // 删除旧版本(保留5个)
])->desc('Deploy project');

特点

  • 自动创建 releases/ 结构
  • 切换符号链接即原子操作
  • 共享目录自动管理(如 storageshared/ 目录)

蓝绿部署 / 金丝雀发布(容器化场景)

如果使用 Docker + Kubernetes,原子部署天然实现:

  • 蓝绿部署:新版本 Pod 全部就绪后,一次性切换 Service 流量
  • 滚动更新:K8s 控制逐步替换 Pod,确保任何时候都有可用的副本

PHP 在容器下的注意事项

  • 构建镜像时就将 PHP 文件打包,不 live mount 代码
  • 利用 opcache.preload 预加载,减少启动开销

数据库迁移的原子性

代码原子部署解决了文件层面的问题,但数据库迁移(如新增字段、改表)也需要原子操作:

  • 向下兼容:新代码兼容旧数据库结构(如先加字段,再改代码读新字段)
  • 分离部署与迁移:先执行迁移脚本,再切换代码版本

示例流程:

执行数据库迁移(加字段、建索引)
2. 切换代码符号链接
3. 清理旧字段(optional,下个版本再drop)

推荐方案

场景 方案
单机 / 低流量 符号链接 + OPcache 清理
多机 / 中等流量 Deployer / Capistrano + 共享存储
容器化 / K8s
(高流量)
蓝绿部署 / 滚动更新

原子部署的核心口诀

新代码先就绪,再瞬间切换入口,不信任“在线覆盖复制”。

抱歉,评论功能暂时关闭!