Quay lại
DevOps✦ Nổi bật
6 phút đọc13 tháng 5, 20261

Zero-Downtime Deployment: Deploy mà user không biết

Làm sao để deploy bản mới lên production mà không ai nhận ra? Cùng tìm hiểu các chiến lược Blue-Green, Rolling, Canary và cách áp dụng thực tế.

N

Nguyễn Nhật Long

@nguyennhatlong1303

So sánh ba chiến lược deployment

Bạn đã bao giờ deploy lúc 2h sáng chưa? Mình thì rồi nhiều lần là đằng khác. Hồi mới đi làm, team mình hay chọn khung giờ "ít traffic nhất" để deploy, rồi cầu nguyện mọi thứ chạy ổn. Mỗi lần nhấn nút deploy là tim đập thình thịch, F5 liên tục xem site còn sống không. Cho đến khi mình biết đến Zero-Downtime Deployment và nhận ra rằng deploy không nhất thiết phải là một trải nghiệm kinh hoàng.

Vậy Zero-Downtime Deployment thực sự là gì?

Nói đơn giản: đây là cách deploy phiên bản mới của ứng dụng mà người dùng không hề hay biết. Không có trang "Hệ thống đang bảo trì", không có lỗi 502, không có request bị drop giữa chừng. Dù bạn đang thay đổi API, cập nhật UI, hay thậm chí migrate database dịch vụ vẫn chạy bình thường 100%.

Nghe có vẻ lý tưởng, nhưng thực tế nó hoàn toàn khả thi. Và với các hệ thống e-commerce, fintech, hay bất kỳ product nào có user thực đây không còn là "nice to have" mà là bắt buộc.

Theo kinh nghiệm của mình, downtime dù chỉ 30 giây cũng có thể gây ra:

  • Mất đơn hàng đang thanh toán dở
  • Transaction bị treo, dữ liệu inconsistent
  • Chỉ số uptime tụt, ảnh hưởng SLA với khách hàng
  • SEO bị Google đánh giá tiêu cực nếu downtime lặp lại

Tại sao deploy lại gây downtime?

Trước khi nói giải pháp, mình muốn bạn hiểu rõ gốc rễ vấn đề. Downtime khi deploy thường đến từ mấy nguyên nhân chính:

Restart service mất thời gian. Khi bạn stop container cũ rồi start container mới, có một khoảng trống mà không ai xử lý request. Dù chỉ vài giây, với hệ thống nhận hàng trăm request/giây thì đó là thảm họa.

Database migration không backward-compatible. Ví dụ bạn rename một column code mới thì đọc tên mới, nhưng code cũ vẫn đang chạy và đọc tên cũ. Boom, lỗi ngay.

Load balancer chưa kịp cập nhật. Khi bạn gỡ server cũ và thêm server mới, có một khoảng delay mà traffic bị route đến instance đã chết.

Deploy in-place. Đây là cách "thô" nhất deploy đè thẳng lên instance đang chạy. User có thể truy cập vào phiên bản "nửa cũ nửa mới", dẫn đến lỗi không đoán trước được.

Ba chiến lược phổ biến để đạt Zero Downtime

Blue-Green Deployment

Đây là chiến lược mình thích nhất vì nó dễ hiểu và rollback cực nhanh.

Ý tưởng rất đơn giản: bạn chạy song song hai môi trường Blue (bản đang production) và Green (bản mới). Khi Green đã test xong, bạn chỉ cần chuyển traffic từ Blue sang Green thông qua Load Balancer. Nếu có lỗi? Chuyển ngược lại trong vài giây.

Sơ đồ Blue-Green Deployment

Trên AWS, bạn có thể dùng Elastic Beanstalk Blue/Green, CodeDeploy kết hợp ALB, hoặc ECS Service với hai Target Group.

Ưu điểm: Rollback gần như instant, không downtime.

Nhược điểm: Tốn tài nguyên gấp đôi vì phải chạy hai môi trường cùng lúc. Với startup nhỏ, chi phí này đáng cân nhắc.

Điều mình thấy hay là Blue-Green buộc team phải nghĩ về infrastructure as code từ đầu. Bạn không thể làm Blue-Green nếu môi trường không reproducible được.

Rolling Deployment

Thay vì thay thế toàn bộ cùng lúc, Rolling Deployment cập nhật từng phần nhỏ — ví dụ 2 trong 10 instance trước, rồi 2 tiếp theo, cho đến hết.

Đây là strategy mặc định trong KubernetesECS. Scheduler sẽ đảm bảo luôn có đủ số lượng pod/task healthy để phục vụ traffic trong suốt quá trình deploy.

Ưu điểm: Tiết kiệm tài nguyên hơn Blue-Green rất nhiều.

Nhược điểm: Rollback phức tạp hơn. Và trong quá trình rolling, hệ thống có thể chạy cả hai version cùng lúc nên API phải backward-compatible.

Theo kinh nghiệm của mình, Rolling hoạt động tốt nhất khi bạn có health check chặt chẽ. Nếu health check quá lỏng, instance lỗi vẫn nhận traffic và user vẫn bị ảnh hưởng.

Canary Deployment

Canary là chiến lược "thận trọng" nhất. Bạn deploy bản mới nhưng chỉ route 5-10% traffic đến nó trước. Sau đó monitor error rate, latency, log nếu mọi thứ ổn thì dần dần tăng lên 50%, rồi 100%.

Trên AWS, bạn có thể dùng CodeDeploy với Weighted Target Group, Route 53 Traffic Weighting, hoặc Lambda Aliases để chia tỉ lệ version.

Ưu điểm: Giảm rủi ro phát hành xuống mức thấp nhất. Nếu có bug, chỉ 5% user bị ảnh hưởng.

Nhược điểm: Yêu cầu hệ thống monitoring tốt CloudWatch, Datadog, Grafana để phát hiện vấn đề sớm. Không có observability tốt thì Canary mất ý nghĩa.

So sánh ba chiến lược deployment

Áp dụng thực tế trên AWS

Với EC2 và ALB, flow cơ bản là:

  1. Auto Scaling Group launch instance mới với version mới
  2. Đợi instance pass health check
  3. ALB bắt đầu route traffic đến instance mới
  4. Drain connection trên instance cũ rồi terminate

Với ECS/EKS, mọi thứ đơn giản hơn nhiều vì orchestrator lo hết. Bạn chỉ cần config deploymentConfiguration với minimumHealthyPercentmaximumPercent hợp lý.

Một tip mà mình hay dùng: set deregistration_delay của Target Group xuống 30-60 giây thay vì mặc định 300 giây. Không ai muốn đợi 5 phút để instance cũ được gỡ ra.

Những điều hay bị bỏ quên

Mình thấy nhiều team focus vào strategy nhưng quên mấy thứ quan trọng không kém:

  • Database migration phải backward-compatible. Đừng bao giờ rename column trực tiếp. Thêm column mới → migrate data → deploy code mới → xóa column cũ. Chia thành nhiều lần deploy.
  • Graceful shutdown. Service cũ phải xử lý xong request đang dở trước khi tắt. Trong Node.js, bạn cần handle signal SIGTERM đúng cách.
  • Health check endpoint phải phản ánh đúng trạng thái. Đừng chỉ return 200 OK. Check cả database connection, Redis connection, dependency services.
  • Feature flags. Kết hợp feature flags với deployment giúp bạn tách biệt "deploy code" và "release feature". Deploy trước, bật feature sau khi đã sẵn sàng.

Bạn nên chọn strategy nào?

Không có câu trả lời đúng cho mọi trường hợp, nhưng đây là cách mình thường quyết định:

  • Startup nhỏ, ít resource: Rolling Deployment trên ECS hoặc Kubernetes. Đơn giản, tiết kiệm.
  • Product đã có user base lớn: Canary để giảm blast radius. Kết hợp monitoring chặt.
  • Cần rollback instant, budget không phải vấn đề: Blue-Green. Đặc biệt phù hợp với fintech hay healthcare.

Điều quan trọng nhất không phải là chọn strategy nào mà là bạn có đang deploy với downtime hay không. Nếu câu trả lời là có, thì bất kỳ strategy nào ở trên cũng là một bước tiến lớn.

Deploy lúc 2h sáng không phải là giải pháp. Xây dựng pipeline đúng cách mới là. Và tin mình đi giấc ngủ ngon hơn nhiều khi bạn biết deploy có thể chạy bất kỳ lúc nào mà không ai bị ảnh hưởng.

NN

Nguyễn Nhật Long

@nguyennhatlong1303

Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.

Thấy hay? Chia sẻ cho bạn bè!

Bài viết liên quan

Có thể bạn cũng thích

Xem tất cả