Tổng quan các chiến lược
| Strategy | Downtime | Risk | Rollback speed | Chi phí |
|---|---|---|---|---|
| Blue-Green | Zero | Thấp | Ngay lập tức (swap) | 2x resource |
| Canary | Zero | Rất thấp | Nhanh (route lại) | +10-20% resource |
| Rolling | Zero | Trung bình | Chậm (roll back từng instance) | Bằng hiện tại |
| Recreate | Có | Cao | Chậm (redeploy) | Bằng hiện tại |
Blue-Green Deployment - Azure App Service Slots
Playbook hoàn chỉnh
bash# 1. Tạo deployment slot (chỉ cần 1 lần)
az webapp deployment slot create \
--name myapp-production \
--resource-group rg-myapp \
--slot staging
# 2. Cấu hình slot settings (không swap theo slot)
az webapp config appsettings set \
--name myapp-production \
--resource-group rg-myapp \
--slot staging \
--settings ASPNETCORE_ENVIRONMENT=Staging
# 3. Deploy code lên staging slot
az webapp deploy \
--name myapp-production \
--resource-group rg-myapp \
--slot staging \
--src-path ./publish.zip \
--type zip
# 4. Warm up staging slot - quan trọng tránh cold start
curl -s https://myapp-production-staging.azurewebsites.net/health
# 5. Swap staging → production (zero downtime)
az webapp deployment slot swap \
--name myapp-production \
--resource-group rg-myapp \
--slot staging \
--target-slot production
# 6. Verify production
curl -s https://myapp-production.azurewebsites.net/health
# ROLLBACK nếu có lỗi - swap ngược lại
az webapp deployment slot swap \
--name myapp-production \
--resource-group rg-myapp \
--slot staging \
--target-slot production
GitHub Actions - Blue-Green Pipeline
yamldeploy-production:
runs-on: ubuntu-latest
environment: production
steps:
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to Staging Slot
uses: azure/webapps-deploy@v3
with:
app-name: myapp-production
slot-name: staging
package: ./publish
- name: Warm Up
run: |
for i in {1..5}; do
curl -sf https://myapp-production-staging.azurewebsites.net/health && break
sleep 10
done
- name: Swap Slots
run: |
az webapp deployment slot swap \
--name myapp-production \
--resource-group rg-myapp \
--slot staging \
--target-slot production
Canary Releases
Dùng Azure App Service traffic routing:
bash# Gửi 10% traffic sang staging slot (canary)
az webapp traffic-routing set \
--name myapp-production \
--resource-group rg-myapp \
--distribution staging=10
# Monitor metrics, nếu OK → tăng dần
az webapp traffic-routing set \
--distribution staging=50
# Hoàn tất → swap
az webapp deployment slot swap \
--name myapp-production \
--resource-group rg-myapp \
--slot staging
# Clear traffic routing
az webapp traffic-routing clear \
--name myapp-production \
--resource-group rg-myapp
Feature Flags - Azure App Configuration
Setup trong .NET
csharp// Program.cs
builder.Configuration.AddAzureAppConfiguration(options =>
{
options.Connect(builder.Configuration["AppConfig:ConnectionString"])
.UseFeatureFlags(flagOptions =>
{
flagOptions.CacheExpirationInterval = TimeSpan.FromSeconds(30);
});
});
builder.Services.AddAzureAppConfiguration();
builder.Services.AddFeatureManagement();
csharp// Controller sử dụng feature flag
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IFeatureManager _featureManager;
public OrdersController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
[HttpPost]
public async Task<IActionResult> CreateOrder(OrderRequest request)
{
if (await _featureManager.IsEnabledAsync("NewOrderFlow"))
{
return await CreateOrderV2(request);
}
return await CreateOrderV1(request);
}
}
bash# Tạo feature flag trong Azure App Configuration
az appconfig feature set \
--name myapp-appconfig \
--feature NewOrderFlow \
--label Production
# Enable feature flag
az appconfig feature enable \
--name myapp-appconfig \
--feature NewOrderFlow \
--label Production
# Disable (rollback feature)
az appconfig feature disable \
--name myapp-appconfig \
--feature NewOrderFlow \
--label Production
Zero-Downtime Database Migration
Database migration là phần khó nhất trong zero-downtime deployment. Nguyên tắc chính:
Expand-Contract Pattern
Ví dụ: Rename column an toàn
csharp// Migration 1: Thêm column mới (deploy cùng app v1)
public partial class AddNewEmailColumn : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Expand: thêm column mới, copy data
migrationBuilder.AddColumn<string>(
name: "EmailAddress",
table: "Users",
nullable: true);
migrationBuilder.Sql(
"UPDATE Users SET EmailAddress = Email");
}
}
// Migration 2: Drop column cũ (deploy cùng app v2, sau khi v1 không còn chạy)
public partial class RemoveOldEmailColumn : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Contract: xoá column cũ
migrationBuilder.DropColumn(
name: "Email",
table: "Users");
}
}
Playbook: Safe Database Migration
bash# 1. Tạo migration
dotnet ef migrations add AddNewEmailColumn
# 2. Generate SQL script (review trước khi chạy)
dotnet ef migrations script --idempotent -o migration.sql
# 3. Review SQL script - check không có breaking changes
# - Không DROP column đang dùng
# - Không ALTER column type không compatible
# - Không thêm NOT NULL constraint trên column cũ
# 4. Apply migration trên staging trước
dotnet ef database update --connection "staging-connection"
# 5. Deploy app mới (tương thích cả schema cũ và mới)
# 6. Verify, sau đó apply migration contract phase
Rollback Procedures
| Tình huống | Hành động | Thời gian |
|---|---|---|
| App lỗi, DB không đổi | Swap slot lại | < 30s |
| App lỗi, DB có migration compatible | Swap slot + keep DB | < 30s |
| App lỗi, DB có breaking migration | Rollback migration + swap slot | 5-30 phút |
| Data corruption | Restore DB backup + redeploy | 30-60 phút |
Best practice: Luôn test rollback procedure trên staging. Tự động hoá rollback trong pipeline với health check gate - nếu health check fail sau deploy, tự động swap lại.