<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CI/CD on Huy Vũ</title><link>https://vuvtdhh.pages.dev/tags/ci/cd/</link><description>Recent content in CI/CD on Huy Vũ</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Huy Vũ</copyright><lastBuildDate>Thu, 16 Jul 2026 00:00:00 +0700</lastBuildDate><atom:link href="https://vuvtdhh.pages.dev/tags/ci/cd/index.xml" rel="self" type="application/rss+xml"/><item><title>Zero-Downtime: Thiết Kế Graceful Shutdown Cho Background Jobs Trong Blue-Green Deployment</title><link>https://vuvtdhh.pages.dev/p/zero-downtime-thi%E1%BA%BFt-k%E1%BA%BF-graceful-shutdown-cho-background-jobs-trong-blue-green-deployment/</link><pubDate>Thu, 16 Jul 2026 00:00:00 +0700</pubDate><guid>https://vuvtdhh.pages.dev/p/zero-downtime-thi%E1%BA%BFt-k%E1%BA%BF-graceful-shutdown-cho-background-jobs-trong-blue-green-deployment/</guid><description>&lt;img src="https://vuvtdhh.pages.dev/p/zero-downtime-thi%E1%BA%BFt-k%E1%BA%BF-graceful-shutdown-cho-background-jobs-trong-blue-green-deployment/blue-green-deployment.jpg" alt="Featured image of post Zero-Downtime: Thiết Kế Graceful Shutdown Cho Background Jobs Trong Blue-Green Deployment" /&gt;&lt;h1 id="quản-lý-lifecycle-và-graceful-shutdown-cho-background-jobs-trong-blue-green-deployment"&gt;Quản Lý Lifecycle Và Graceful Shutdown Cho Background Jobs Trong Blue-Green Deployment
&lt;/h1&gt;&lt;p&gt;Trong các hệ thống Enterprise, Blue-Green Deployment là tiêu chuẩn để đạt zero-downtime. Khác với các Stateless Web API nơi việc thực hiện traffic routing giữa hai môi trường Blue và Green diễn ra khá đơn giản, kiến trúc sẽ phức tạp hơn đáng kể khi tích hợp các Background Job Workers như Hangfire, Celery hoặc RabbitMQ Consumers.&lt;/p&gt;
&lt;p&gt;Tài liệu này phân tích bài toán gián đoạn Background Jobs và phương pháp quản lý Lifecycle kết hợp Graceful Shutdown, nhằm đảm bảo Data Integrity trong quá trình deployment.&lt;/p&gt;
&lt;h2 id="1-tại-sao-cần-graceful-shutdown-cho-background-jobs"&gt;1. Tại Sao Cần Graceful Shutdown Cho Background Jobs?
&lt;/h2&gt;&lt;p&gt;Khác với HTTP Request có response time tính bằng milliseconds, Background Jobs thường là long-running task và mang tính Stateful. Ví dụ: generate report, bulk email, hoặc data synchronization giữa các ERP.&lt;/p&gt;
&lt;p&gt;Khi CI/CD deploy phiên bản Green và shutdown môi trường Blue thông qua lệnh Stop IIS App Pool hoặc Kill Container, thao tác Hard Stop sẽ gây ra các system failure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Thread Abort:&lt;/strong&gt; Worker process bị OS terminate lập tức. Nếu Job đang xử lý I/O operation hoặc uncommitted database transaction, hệ thống sẽ gặp &lt;strong&gt;data corruption&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zombie Job:&lt;/strong&gt; Tác vụ bị ngắt ngang nhưng hệ thống quản lý như Hangfire Storage không nhận được fault signal. Job kẹt ở trạng thái Processing trên database, đòi hỏi can thiệp manual từ admin.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incomplete Asynchronous Flow:&lt;/strong&gt; Các tiến trình nghiệp vụ bất đồng bộ không trả về kết quả cuối cùng, làm gãy luồng thao tác phía client.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graceful Shutdown là cơ chế bắt buộc. Hệ thống cần một khoảng buffer time để hoàn tất các task đang chạy thay vì bị rút resource đột ngột.&lt;/p&gt;
&lt;h2 id="2-pipeline-cicd-blue-green-deployment"&gt;2. Pipeline CI/CD Blue-Green Deployment
&lt;/h2&gt;&lt;p&gt;Để giải quyết bài toán trên, pipeline CI/CD phải điều phối nhịp nhàng hai luồng workload có tính chất trái ngược:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;HTTP Web Traffic (Synchronous):&lt;/strong&gt; Reroute tức thì qua Load Balancer (IIS ARR, Nginx).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Background Workload (Asynchronous):&lt;/strong&gt; Yêu cầu thời gian chờ hoàn tất các tác vụ dang dở (Drain) trước khi shutdown.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dưới đây là các bước thực thi tiêu chuẩn cho một kịch bản CI/CD với Blue-Green Deployment:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Resolve Target &amp;amp; Sync Artifacts:&lt;/strong&gt; Xác định slot mục tiêu (ví dụ: Green slot) và thực hiện đồng bộ mã nguồn phiên bản mới (thông qua Robocopy hoặc các công cụ tương đương).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update Configuration &amp;amp; Activate:&lt;/strong&gt; Cập nhật các biến môi trường và khởi động ứng dụng trên IIS Target Slot.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Direct Health Check:&lt;/strong&gt; Thực hiện HTTP Health Probe trực tiếp vào slot mới để xác nhận ứng dụng đã khởi động và sẵn sàng xử lý request.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graceful Drain:&lt;/strong&gt; Kích hoạt API Command gửi tín hiệu drain cho slot đang chạy (Blue). Ứng dụng nhận tín hiệu và lập tức ngưng kéo Job mới.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disable Live Slot Routing:&lt;/strong&gt; Cấu hình lại Application Request Routing (ARR) hoặc Load Balancer để ngắt luồng traffic hiện tại của slot Blue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Routing Verification:&lt;/strong&gt; Xác minh Load Balancer đã hoàn tất việc chuyển hướng 100% incoming traffic sang slot Green.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decommission:&lt;/strong&gt; CI/CD Runner delay hoặc inject một Scheduled Task vào host OS để lên lịch decommission cho slot Blue.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Trong quy trình trên, phần cốt lõi bảo vệ Background Jobs nằm ở sự phối hợp giữa &lt;strong&gt;Bước 4&lt;/strong&gt; và &lt;strong&gt;Bước 7&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="3-system-design-làm-thế-nào-để-graceful-drain"&gt;3. System Design: Làm Thế Nào Để Graceful Drain?
&lt;/h2&gt;&lt;p&gt;Quá trình shutdown môi trường (giả sử cần shutdown Green) phải được thiết kế thành một luồng Draining chuẩn mực, đồng bộ giữa pipeline CI/CD và application code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Signal Stop:&lt;/strong&gt; CI/CD trigger một Management Endpoint (API Command) vào môi trường Green. Lệnh này không shutdown application mà chỉ thị cho Background Job server ngừng fetch tác vụ mới từ Queue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Drain:&lt;/strong&gt; Môi trường Green bị cô lập với task mới. Toàn bộ incoming workload được route sang môi trường Green. Các active worker ở Green tiếp tục xử lý đến khi hoàn tất các task hiện tại.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delay Timeout:&lt;/strong&gt; CI/CD pipeline pause một khoảng buffer time, tương đương với duration của long-running job nặng nhất trong hệ thống.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dispose:&lt;/strong&gt; Hết thời gian timeout, hạ tầng gửi SIGTERM hoặc Stop App Pool command. Lúc này các worker đều ở trạng thái idle, ứng dụng release resource và ngắt kết nối an toàn.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="4-lifecycle-management-với-dependency-injection"&gt;4. Lifecycle Management Với Dependency Injection
&lt;/h2&gt;&lt;p&gt;Rào cản kỹ thuật lớn nhất khi implement luồng Drain là các memory exception như &lt;code&gt;ObjectDisposedException&lt;/code&gt; hoặc Resource Leak. Căn nguyên thường đến từ việc can thiệp sai cách vào lifecycle của Dependency Injection (DI) hoặc IoC Container.&lt;/p&gt;
&lt;h3 id="anti-pattern-manual-disposal"&gt;Anti-Pattern: Manual Disposal
&lt;/h3&gt;&lt;p&gt;Nhiều thiết kế mắc sai lầm khi cố gắng tự gọi lệnh hủy đối tượng (Dispose/Teardown) ngay tại Management Endpoint nhận tín hiệu Drain, hoặc can thiệp thủ công vào các sự kiện tắt mở của Application Framework. Điều này dẫn đến &lt;strong&gt;Race Condition&lt;/strong&gt; khi OS thực sự terminate process. Framework tự động dọn dẹp tài nguyên nhưng lại truy cập vào vùng nhớ đã bị ứng dụng deallocate thủ công từ trước, gây crash hệ thống ở những giây cuối cùng.&lt;/p&gt;
&lt;h3 id="best-practice-delegate-cho-di-container"&gt;Best Practice: Delegate cho DI Container
&lt;/h3&gt;&lt;p&gt;Triết lý thiết kế chuẩn mực trong các framework hiện đại: &lt;em&gt;Component nào khởi tạo resource, component đó chịu trách nhiệm deallocate.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;State Mutation Only:&lt;/strong&gt; Tại Management Endpoint, chỉ phát tín hiệu (signal) để hệ thống Background Job (như Hangfire Server) ngừng fetch tác vụ mới. Tuyệt đối không can thiệp vào bộ nhớ hoặc tự gọi hàm &lt;code&gt;Dispose()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hosted Service Registration:&lt;/strong&gt; Đảm bảo Job Server được đăng ký tích hợp sâu vào DI Container (thường thông qua &lt;code&gt;IHostedService&lt;/code&gt; hoặc &lt;code&gt;BackgroundService&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Framework Delegation:&lt;/strong&gt; Khi thời gian Timeout kết thúc và OS gửi lệnh Terminate, framework đã có sẵn cơ chế kích hoạt &lt;code&gt;Dispose()&lt;/code&gt; tuần tự cho mọi instance do DI quản lý. Việc ủy quyền hoàn toàn quá trình dọn dẹp này cho Root Container giúp loại trừ triệt để rủi ro rò rỉ tài nguyên, đảm bảo hệ thống tắt một cách an toàn.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lời kết:&lt;/strong&gt; Trong kiến trúc Enterprise, Blue-Green Deployment không chỉ đơn thuần là bài toán chuyển hướng traffic ở Load Balancer. Để đạt được True Zero-Downtime, xử lý mượt mà các Stateful Background Jobs chính là mảnh ghép khó nhất nhưng bắt buộc phải có.&lt;/p&gt;
&lt;/blockquote&gt;</description></item></channel></rss>