本文目录导读:

我来详细解释一下PHP的蓝绿部署策略。
什么是蓝绿部署
蓝绿部署是一种零停机部署策略,通过维护两套完全相同但独立的环境(蓝色和绿色)来实现。
PHP蓝绿部署实现方案
基本架构
用户请求 → 负载均衡器 → 蓝环境 或 绿环境
具体实现方式
使用Nginx + 符号链接
# nginx配置示例
upstream php_backend {
# 使用unix socket更高效
server unix:/var/run/php/php-fpm-blue.sock;
# server unix:/var/run/php/php-fpm-green.sock;
}
server {
listen 80;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php_backend;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
使用负载均衡器(HAProxy)
# haproxy配置
frontend php_frontend
bind *:80
default_backend php_blue
backend php_blue
server php-blue-1 192.168.1.101:80 check
server php-blue-2 192.168.1.102:80 check
backend php_green
server php-green-1 192.168.1.201:80 check
server php-green-2 192.168.1.202:80 check
PHP部署脚本示例
<?php
// blue-green-deploy.php
class BlueGreenDeployment {
private $bluePath = '/var/www/blue';
private $greenPath = '/var/www/green';
private $activeSymlink = '/var/www/current';
/**
* 部署到非活动环境
*/
public function deployToInactive() {
$inactiveEnv = $this->getInactiveEnvironment();
$deployPath = ($inactiveEnv === 'blue') ? $this->bluePath : $this->greenPath;
echo "Deploying to {$inactiveEnv} environment...\n";
// 1. 拉取最新代码
$this->pullLatestCode($deployPath);
// 2. 安装依赖
$this->installDependencies($deployPath);
// 3. 运行数据库迁移
$this->runMigrations($deployPath);
// 4. 执行测试
if ($this->runTests($deployPath)) {
echo "Tests passed. Switching traffic...\n";
$this->switchTraffic();
} else {
echo "Tests failed. Aborting deployment.\n";
}
}
/**
* 获取当前非活动环境
*/
private function getInactiveEnvironment() {
$current = readlink($this->activeSymlink);
return (strpos($current, 'blue') !== false) ? 'green' : 'blue';
}
/**
* 切换流量到新的环境
*/
private function switchTraffic() {
$newEnv = $this->getInactiveEnvironment();
$newPath = ($newEnv === 'blue') ? $this->bluePath : $this->greenPath;
// 更新符号链接
unlink($this->activeSymlink);
symlink($newPath, $this->activeSymlink);
echo "Traffic switched to {$newEnv} environment.\n";
// 等待一段时间确保所有请求完成
sleep(10);
// 可以清理旧环境
$this->cleanOldEnvironment();
}
private function pullLatestCode($path) {
chdir($path);
exec('git pull origin master', $output, $returnCode);
return $returnCode === 0;
}
private function installDependencies($path) {
chdir($path);
exec('composer install --no-dev --optimize-autoloader', $output, $returnCode);
return $returnCode === 0;
}
private function runMigrations($path) {
chdir($path);
exec('php artisan migrate --force', $output, $returnCode);
return $returnCode === 0;
}
private function runTests($path) {
chdir($path);
exec('php vendor/bin/phpunit', $output, $returnCode);
return $returnCode === 0;
}
private function cleanOldEnvironment() {
$oldEnv = $this->getInactiveEnvironment();
echo "Old environment ({$oldEnv}) can be cleaned up.\n";
}
}
// 使用示例
$deployer = new BlueGreenDeployment();
$deployer->deployToInactive();
部署流程
#!/bin/bash
# deploy.sh
# 1. 确定当前活动环境
CURRENT=$(readlink /var/www/current)
if [[ $CURRENT == *"blue"* ]]; then
TARGET="green"
TARGET_PATH="/var/www/green"
else
TARGET="blue"
TARGET_PATH="/var/www/blue"
fi
echo "Deploying to $TARGET environment..."
# 2. 部署代码
cd $TARGET_PATH
git pull origin main
composer install --no-dev --optimize-autoloader
# 3. 运行迁移
php artisan migrate --force
# 4. 清除缓存
php artisan optimize
# 5. 切换流量
ln -sfn $TARGET_PATH /var/www/current
echo "Traffic switched to $TARGET environment"
# 6. 重启PHP-FPM
sudo systemctl reload php8.1-fpm
# 7. 验证部署
curl -I http://localhost/health-check
Docker实现蓝绿部署
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
depends_on:
- php-blue
- php-green
php-blue:
build: ./php
volumes:
- /var/www/blue:/var/www/html
environment:
- APP_ENV=production
- APP_COLOR=blue
php-green:
build: ./php
volumes:
- /var/www/green:/var/www/html
environment:
- APP_ENV=production
- APP_COLOR=green
健康检查端点
<?php
// health.php - 放在应用根目录
header('Content-Type: application/json');
$healthData = [
'status' => 'healthy',
'environment' => getenv('APP_COLOR') ?: 'unknown',
'timestamp' => date('Y-m-d H:i:s'),
'php_version' => phpversion(),
'db_connection' => checkDatabaseConnection(),
'cache_status' => checkCache()
];
echo json_encode($healthData);
function checkDatabaseConnection() {
try {
// 数据库连接检查
return true;
} catch (\Exception $e) {
return false;
}
}
function checkCache() {
// Redis/Memcached检查
return true;
}
最佳实践建议
- 数据库兼容性:确保新旧两个版本的应用能兼容同一数据库结构
- 会话管理:使用外部会话存储(Redis/数据库)而非文件存储
- 缓存清空:切换前清空OpCache、应用缓存
- 监控告警:部署后密切监控错误率和响应时间
- 回滚策略:保留上一个版本的部署,便于快速回滚
- 渐进切换:可以先切换10%的流量,观察无问题后再完全切换
蓝绿部署能有效减少部署风险,但需要合理的资源规划和配置管理。