PHP项目版本管理与回滚

wen PHP项目 2

本文目录导读:

PHP项目版本管理与回滚

  1. 版本控制系统(Git)基础
  2. 部署策略
  3. 数据库回滚策略
  4. 自动化部署工具
  5. CI/CD 集成
  6. 最佳实践
  7. 常见问题处理

针对PHP项目的版本管理与回滚,以下是几种主流的实践方案,涵盖从简单到专业的场景。

版本控制系统(Git)基础

Git分支策略

# 主分支
main / master     # 生产环境
develop           # 开发环境
# 功能分支
feature/*         # 新功能开发
bugfix/*          # Bug修复
release/*         # 发布准备
# 热修复分支
hotfix/*          # 紧急修复

版本标记

# 语义化版本标记
git tag v1.0.0
git tag v1.1.0-beta
git tag v2.0.0-rc1
# 推送到远程
git push origin --tags

部署策略

1 手动备份回滚(简单项目)

# 部署脚本示例
#!/bin/bash
PROJECT_DIR="/var/www/myapp"
BACKUP_DIR="/var/backups/myapp"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# 创建备份
tar -czf "${BACKUP_DIR}/backup_${TIMESTAMP}.tar.gz" -C "${PROJECT_DIR}" .
# 部署新版本
cd ${PROJECT_DIR}
git pull origin main
# 回滚操作
rollback() {
    local backup_file=$1
    if [ -f "$backup_file" ]; then
        rm -rf ${PROJECT_DIR}/*
        tar -xzf "$backup_file" -C ${PROJECT_DIR}
        echo "回滚完成: $backup_file"
    fi
}

2 符号链接切换(推荐)

// 项目目录结构
/var/www/
├── releases/
│   ├── 20240101_100000/   # v1.0.0
│   ├── 20240115_143000/   # v1.1.0
│   └── 20240201_090000/   # v1.2.0
├── shared/                # 共享资源
│   ├── .env
│   ├── storage/
│   └── uploads/
└── current -> releases/20240201_090000/  # 当前版本符号链接

部署脚本

#!/bin/bash
RELEASES_DIR="/var/www/releases"
SHARED_DIR="/var/www/shared"
CURRENT_LINK="/var/www/current"
deploy() {
    # 1. 创建新版本目录
    RELEASE_DIR="${RELEASES_DIR}/$(date +%Y%m%d_%H%M%S)"
    mkdir -p $RELEASE_DIR
    # 2. 克隆代码
    git clone -b main git@github.com:user/repo.git $RELEASE_DIR
    # 3. 安装依赖
    cd $RELEASE_DIR
    composer install --no-dev --optimize-autoloader
    # 4. 设置共享资源链接
    ln -nfs $SHARED_DIR/.env $RELEASE_DIR/.env
    ln -nfs $SHARED_DIR/storage $RELEASE_DIR/storage
    # 5. 切换符号链接
    ln -nfs $RELEASE_DIR $CURRENT_LINK
    # 6. 执行迁移
    cd $CURRENT_LINK
    php artisan migrate --force
}
rollback() {
    # 回滚到上一个版本
    PREVIOUS_RELEASE=$(ls -t $RELEASES_DIR | head -n 2 | tail -n 1)
    ln -nfs "${RELEASES_DIR}/${PREVIOUS_RELEASE}" $CURRENT_LINK
    # 如果有数据库迁移,需要回滚
    cd $CURRENT_LINK
    php artisan migrate:rollback
}

数据库回滚策略

Laravel Migration

// 创建迁移
php artisan make:migration add_price_to_products
// 执行迁移
php artisan migrate
// 回滚
php artisan migrate:rollback
php artisan migrate:reset
php artisan migrate:refresh  // 回滚并重新迁移

手动数据库备份

-- 备份脚本
mysqldump -u root -p mydatabase > backup_20240101.sql
-- 恢复
mysql -u root -p mydatabase < backup_20240101.sql

自动化部署工具

1 Deployer(PHP官方推荐)

// deploy.php
namespace Deployer;
require 'recipe/laravel.php';
// 项目配置
set('application', 'my_app');
set('repository', 'git@github.com:user/repo.git');
set('php_version', '8.1');
// 服务器配置
host('production')
    ->setHostname('example.com')
    ->set('remote_user', 'deploy')
    ->set('deploy_path', '/var/www/myapp');
// 任务
task('deploy', [
    'deploy:info',
    'deploy:prepare',
    'deploy:lock',
    'deploy:release',
    'deploy:update_code',
    'deploy:shared',
    'deploy:vendors',
    'deploy:writable',
    'artisan:storage:link',
    'artisan:view:cache',
    'artisan:config:cache',
    'artisan:migrate',
    'deploy:symlink',
    'deploy:unlock',
    'cleanup',
]);
// 回滚
task('rollback', function () {
    $releases = get('releases_list');
    if (isset($releases[1])) {
        $rollbackRelease = $releases[1];
        run("cd {{deploy_path}} && {{bin/symlink}} -f releases/{$rollbackRelease} current");
        run("cd {{deploy_path}} && rm -rf releases/{$releases[0]}");
        writeln("Rolled back to {$rollbackRelease}");
    }
});

2 Capistrano

# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/composer'
require 'capistrano/file-permissions'
# config/deploy.rb
set :application, 'my_app'
set :repo_url, 'git@github.com:user/repo.git'
set :deploy_to, '/var/www/myapp'
set :keep_releases, 5
namespace :deploy do
  after :updated, 'composer:install'
  after :published, :restart
  desc 'Rollback to previous release'
  task :rollback do
    on roles(:app) do
      execute "cd #{deploy_to} && ls -t releases | head -n 2 | tail -n 1"
    end
  end
end

CI/CD 集成

GitHub Actions

name: Deploy to Production
on:
  push:
    branches: [ main ]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.1'
      - name: Deploy to Server
        uses: deployphp/action@v1
        with:
          dep: deploy production
          private-key: ${{ secrets.SSH_PRIVATE_KEY }}

最佳实践

1 版本号管理

  • 使用语义化版本(SemVer):主版本.次版本.修订号
  • composer.json 中记录版本

2 变更日志

# CHANGELOG.md
## [1.2.0] - 2024-01-15
### Added
- New payment gateway integration
- User notification system
### Changed
- Updated dependencies
- Improved performance
### Fixed
- Login session timeout issue
- Database connection pool exhaustion
## [1.1.0] - 2024-01-01
### Added
- Product search functionality

3 健康检查

// health.php
<?php
// 部署后验证
$checks = [
    'database' => function() {
        try {
            DB::connection()->getPdo();
            return true;
        } catch (\Exception $e) {
            return false;
        }
    },
    'cache' => function() {
        return Cache::store('redis')->set('health_check', time());
    },
    'queue' => function() {
        return Queue::size() < 1000; // 队列长度检查
    }
];
foreach ($checks as $name => $check) {
    if (!$check()) {
        // 触发回滚
        exec('php artisan deploy:rollback');
        die("Health check failed: {$name}");
    }
}

4 回滚策略决策树

是否影响数据库?
├── 是
│   ├── 是否可逆迁移?
│   │   ├── 是 → 执行 migrate:rollback
│   │   └── 否 → 手动修复数据库 + 代码回滚
│   └── 否 → 直接回滚代码
└── 否 → 直接回滚代码
是否影响缓存/队列?
├── 是 → 清理相关缓存/队列
└── 否 → 无需处理

常见问题处理

1 紧急回滚脚本

#!/bin/bash
# emergency-rollback.sh
RELEASES_DIR="/var/www/releases"
CURRENT_LINK="/var/www/current"
# 自动检测问题版本
CURRENT_RELEASE=$(readlink -f $CURRENT_LINK)
CURRENT_RELEASE_NAME=$(basename $CURRENT_RELEASE)
# 获取上一个版本
PREVIOUS_RELEASE=$(ls -t $RELEASES_DIR | grep -v "^$CURRENT_RELEASE_NAME$" | head -n 1)
if [ -n "$PREVIOUS_RELEASE" ]; then
    # 切换符号链接
    ln -nfs "${RELEASES_DIR}/${PREVIOUS_RELEASE}" $CURRENT_LINK
    # 数据库回滚
    cd $CURRENT_LINK
    php artisan down
    php artisan migrate:rollback
    php artisan up
    echo "紧急回滚完成: $CURRENT_RELEASE_NAME → $PREVIOUS_RELEASE"
else
    echo "错误: 没有可用的回滚版本"
    exit 1
fi

通过这些方案,你可以根据项目规模和团队需求选择合适的版本管理和回滚策略,建议从小规模开始,逐步完善自动化流程。

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