本文目录导读:

我来详细讲解 PHP 应用的蓝绿部署策略。
什么是蓝绿部署
蓝绿部署是一种零停机部署策略,通过维护两个相同的生产环境(蓝色和绿色),在版本切换时实现无缝更新。
基本架构
┌─────────────┐
│ 负载均衡器 │
│ (Nginx/LB) │
└─────┬───────┘
│
┌───────────┼───────────┐
│ │ │
┌─────▼─────┐ ┌───▼─────────┐
│ 蓝色环境 │ │ 绿色环境 │
│ (当前版本) │ │ (新版本) │
└───────────┘ └─────────────┘
实现方案
基于 Nginx 的蓝绿部署
# nginx.conf
upstream blue_green {
# 当前活跃环境
server 192.168.1.10:8080; # 蓝色环境
# server 192.168.1.11:8080; # 绿色环境(部署时切换)
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://blue_green;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
切换部署脚本:
#!/bin/bash # deploy.sh # 切换到绿色环境 echo "Switching to Green environment..." # 1. 更新 Nginx 配置 sed -i 's/192.168.1.10/192.168.1.11/g' /etc/nginx/nginx.conf # 2. 测试配置 nginx -t # 3. 重载 Nginx nginx -s reload # 4. 验证 curl -s http://example.com/healthcheck
基于 Docker 容器的蓝绿部署
# docker-compose.yml
version: '3.8'
services:
app-blue:
image: myapp:blue
container_name: app-blue
ports:
- "8080:80"
networks:
- app-network
app-green:
image: myapp:green
container_name: app-green
ports:
- "8081:80"
networks:
- app-network
networks:
app-network:
driver: bridge
自动化部署脚本:
#!/bin/bash
# blue-green-deploy.sh
# 获取当前活跃环境
ACTIVE_BLUE=$(docker ps --filter "name=app-blue" --format "{{.Names}}" | wc -l)
if [ "$ACTIVE_BLUE" -gt 0 ]; then
# 当前蓝环境活跃,部署到绿环境
echo "Deploying to Green environment..."
# 1. 构建新版本
docker build -t myapp:green .
# 2. 启动绿色容器
docker-compose up -d app-green
# 3. 健康检查
if curl -f http://localhost:8081/health; then
echo "Green environment is healthy"
# 4. 切换流量到绿色
sed -i 's/app-blue/app-green/g' /etc/nginx/nginx.conf
nginx -s reload
# 5. 停止蓝色环境
docker-compose stop app-blue
else
echo "Deployment failed, rolling back"
docker-compose stop app-green
fi
else
# 当前绿环境活跃,部署到蓝环境
echo "Deploying to Blue environment..."
docker build -t myapp:blue .
docker-compose up -d app-blue
if curl -f http://localhost:8080/health; then
sed -i 's/app-green/app-blue/g' /etc/nginx/nginx.conf
nginx -s reload
docker-compose stop app-green
else
docker-compose stop app-blue
fi
fi
基于 Kubernetes 的蓝绿部署
# blue-green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
labels:
app: myapp
version: blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: php-app
image: myapp:1.0.0
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
labels:
app: myapp
version: green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: php-app
image: myapp:1.1.0
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
version: blue # 切换时为 green
ports:
- port: 80
targetPort: 80
PHP 应用注意事项
数据库兼容性
// 处理数据库迁移
class DatabaseMigration {
public function checkCompatibility() {
// 检查新旧版本数据库兼容性
$currentVersion = $this->getSchemaVersion();
if ($currentVersion < $this->targetVersion) {
// 可以在切换前执行迁移
$this->migrateDatabase();
}
}
}
会话管理
// 使用共享会话存储(如 Redis)
session_set_save_handler(
new RedisSessionHandler($redis)
);
// 或者配置 session 存储
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://redis-server:6379');
配置文件管理
// config.php
class AppConfig {
public static function getEnvironment() {
// 通过环境变量识别当前环境
return getenv('APP_ENV') ?: 'blue';
}
public static function getDatabaseConfig() {
$env = self::getEnvironment();
return [
'blue' => [
'host' => 'db-blue.example.com',
'database' => 'app_blue'
],
'green' => [
'host' => 'db-green.example.com',
'database' => 'app_green'
]
][$env];
}
}
健康检查实现
// healthcheck.php
<?php
header('Content-Type: application/json');
$checks = [
'database' => checkDatabase(),
'cache' => checkCache(),
'filesystem' => is_writable('/var/www/app')
];
foreach ($checks as $name => $passed) {
if (!$passed) {
http_response_code(500);
echo json_encode(['status' => 'error', 'check' => $name]);
exit;
}
}
echo json_encode(['status' => 'healthy']);
自动化部署工具
使用 Ansible
# deploy.yml
---
- hosts: webservers
tasks:
- name: Deploy new version to inactive environment
shell: |
if [ -f /var/www/blue/index.php ]; then
echo "Deploying to green"
cp -r /tmp/release/* /var/www/green/
else
echo "Deploying to blue"
cp -r /tmp/release/* /var/www/blue/
fi
- name: Run health check
uri:
url: "http://localhost/healthcheck"
return_content: yes
register: health_check
- name: Switch traffic
file:
path: /etc/nginx/sites-enabled/myapp
state: link
src: /etc/nginx/sites-available/myapp-green.conf
when: health_check.content is search('healthy')
使用 Jenkins Pipeline
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
stage('Deploy to Inactive') {
steps {
script {
def activeEnv = sh(script: 'curl -s https://api.example.com/active', returnStdout: true)
def targetEnv = activeEnv.trim() == 'blue' ? 'green' : 'blue'
sh "docker tag myapp:${BUILD_NUMBER} myapp:${targetEnv}"
sh "docker-compose up -d app-${targetEnv}"
}
}
}
stage('Switch Traffic') {
steps {
script {
def activeEnv = sh(script: 'curl -s https://api.example.com/active', returnStdout: true)
def targetEnv = activeEnv.trim() == 'blue' ? 'green' : 'blue'
sh "sed -i 's/${activeEnv}/${targetEnv}/g' /etc/nginx/nginx.conf"
sh 'nginx -s reload'
}
}
}
}
}
最佳实践
-
自动回滚机制
- 健康检查失败时自动回滚
- 监控响应时间和错误率
-
数据同步
- 切换前确保数据库同步
- 使用数据库复制或多主数据库
-
缓存清理
- 切换时清理 OpCache
- 刷新 CDN 缓存
-
监控告警
- 实时监控两个环境
- 设置切换时的性能指标对比
-
灰度发布
- 可以结合按比例分配流量
- 逐步增加新环境流量
蓝绿部署能显著降低发布风险,但需要确保两个环境配置完全一致,并做好数据同步机制。