Giới thiệu
Trong một hệ thống phân tán, bạn không bao giờ biết điều gì sẽ xảy ra hoặc khi nào mọi thứ có thể sai. Các sự cố mạng, hỏng hóc thành phần, hoặc thậm chí một bộ định tuyến không hoạt động có thể gây ra nhiều rắc rối. Là một kỹ sư phần mềm, nhiệm vụ của bạn là giữ cho các hệ thống này bền bỉ và hoạt động liên tục. Đó chính là lý do mô hình Circuit Breaker ra đời - một mẫu thiết kế giúp ngăn ngừa các hỏng hóc lan truyền và giữ cho dịch vụ của bạn hoạt động trơn tru.
Mô Hình Circuit Breaker Là Gì?
Định Nghĩa
Mô hình Circuit Breaker dừng cuộc gọi dịch vụ khi phát hiện rằng dịch vụ đang gặp sự cố, giống như một cầu dao điện trong nhà bạn. Khi một dịch vụ không phản hồi, mô hình này sẽ dừng các yêu cầu tiếp theo đến dịch vụ đó, giúp bảo vệ hệ thống khỏi sự sụp đổ hoàn toàn.
Cách Hoạt Động
- Một consumer gửi yêu cầu đến nhiều dịch vụ.
- Nếu một dịch vụ không hoạt động, consumer sẽ tiếp tục gửi yêu cầu mà không biết rằng dịch vụ đó đã hỏng.
- Mô hình Circuit Breaker sẽ tạo ra một proxy, hoạt động như một rào cản giữa consumer và dịch vụ.
- Khi số lần thất bại vượt quá ngưỡng, circuit breaker sẽ được kích hoạt, chặn các yêu cầu tiếp theo trong một khoảng thời gian nhất định.
- Trong thời gian này, các yêu cầu đến dịch vụ không phản hồi sẽ bị từ chối ngay lập tức.
- Sau thời gian chờ, circuit breaker sẽ cho phép một vài yêu cầu kiểm tra. Nếu thành công, nó sẽ quay lại hoạt động bình thường; nếu thất bại, thời gian chờ sẽ được khởi động lại.
Tình Huống Sử Dụng Chính: Hệ Thống Quản Lý Nhân Sự
Hãy lấy một ví dụ thực tế về hệ thống quản lý nhân sự dựa trên microservices của một công ty hư cấu, Mercantile Finance. Hệ thống này bao gồm bốn dịch vụ:
- Dịch vụ 1: Lấy thông tin cá nhân.
- Dịch vụ 2: Lấy thông tin nghỉ phép.
- Dịch vụ 3: Cung cấp dữ liệu hiệu suất nhân viên.
- Dịch vụ 4: Xử lý thông tin phân bổ.
Các dịch vụ này được gọi thông qua một mô hình aggregator, nơi một proxy điều phối các yêu cầu đến nhiều dịch vụ backend. Nếu một dịch vụ gặp sự cố, toàn bộ hệ thống có thể bị ảnh hưởng - trừ khi chúng ta sử dụng một circuit breaker.
Tại Sao Tính Khả Dụng Quan Trọng Trong Microservices
Tính khả dụng là rất quan trọng trong microservices vì thời gian ngừng hoạt động có thể tích lũy nhanh chóng. Giả sử Mercantile Finance cam kết 99.999% thời gian hoạt động (còn gọi là "năm chín"). Đây là cách tính toán:
- Tính toán:
- 24 giờ/ngày × 365 ngày/năm = 8,760 giờ/năm.
- 8,760 giờ × 60 = 525,600 phút/năm.
- 99.999% thời gian hoạt động cho phép 0.001% thời gian ngừng hoạt động.
- 525,600 × 0.001% = 5.256 phút thời gian ngừng hoạt động mỗi năm.
Đối với một hệ thống monolithic, 5.25 phút thời gian ngừng hoạt động là có thể chấp nhận được. Nhưng trong kiến trúc microservices với, ví dụ, 100 dịch vụ, điều đó có thể lên tới 8.78 giờ thời gian ngừng hoạt động mỗi năm nếu mỗi dịch vụ gặp sự cố một cách độc lập. 😱 Đây chính là lý do tại sao việc bảo vệ các dịch vụ bằng các mẫu như Circuit Breaker là rất cần thiết.
Nguyên Nhân Gây Ra Hỏng Hóc Dịch Vụ
Chúng ta hãy xem xét hai kịch bản hỏng hóc phổ biến trong microservices và cách chúng có thể làm hỏng hệ thống của bạn.
Kịch Bản 1: Ngăn Chặn Luồng Tài Nguyên
Hãy tưởng tượng một máy chủ web đang xử lý yêu cầu cho năm dịch vụ. Khi một yêu cầu đến, máy chủ phân bổ một luồng để gọi dịch vụ. Nếu một dịch vụ chậm hoặc không phản hồi, các luồng sẽ chờ, chiếm dụng tài nguyên. Đối với một dịch vụ có nhu cầu cao, nhiều luồng hơn sẽ được phân bổ, dẫn đến một hàng đợi các yêu cầu bị chặn.
Nếu hầu hết các luồng bị chiếm dụng bởi dịch vụ gặp sự cố, các yêu cầu đến sẽ bị xếp hàng, làm cho hệ thống quá tải. Ngay cả khi dịch vụ đó hồi phục, các yêu cầu đã xếp hàng sẽ tràn vào nó, có thể gây ra một hỏng hóc khác.
Kịch Bản 2: Hỏng Hóc Lan Truyền
Hãy xem xét một chuỗi dịch vụ: A → B → C → D. Nếu D không phản hồi, sự cố sẽ lan ra khắp chuỗi, gây ra một hỏng hóc lan truyền.
Những kịch bản này nhấn mạnh tại sao chúng ta cần một cơ chế để phát hiện và cách ly các hỏng hóc một cách nhanh chóng.
Mô Hình Circuit Breaker Cứu Giúp
Mô hình Circuit Breaker bao quanh các cuộc gọi dịch vụ bằng một đối tượng circuit breaker theo dõi các hỏng hóc. Nó có ba trạng thái:
- Đóng: Hoạt động bình thường; các yêu cầu đi qua dịch vụ.
- Mở: Quá nhiều hỏng hóc đã được phát hiện; các yêu cầu bị chặn và trả về lỗi ngay lập tức.
- Bán Mở: Sau một khoảng thời gian chờ, một vài yêu cầu kiểm tra được cho phép. Nếu chúng thành công, circuit trở lại trạng thái Đóng; nếu không, nó vẫn ở trạng thái Mở.
Trong hệ thống quản lý nhân sự của chúng ta:
- Giả sử Dịch vụ A (thông tin cá nhân) nên phản hồi trong 200ms.
- 0–100ms: Hoạt động bình thường.
- 100–200ms: Rủi ro, nhưng chấp nhận được.
-
200ms: Hỏng hóc; circuit breaker sẽ kích hoạt.
- Nếu 75% yêu cầu vượt quá 150ms, circuit breaker phát hiện một dịch vụ chậm.
- Nếu yêu cầu vượt quá 200ms, proxy sẽ đánh dấu Dịch vụ A là không phản hồi và kích hoạt circuit sang trạng thái Mở.
- Các yêu cầu đến Dịch vụ A sẽ ngay lập tức thất bại với một lỗi, ngăn chặn việc tiêu tốn tài nguyên.
- Trong nền, circuit breaker sẽ gửi các yêu cầu ping định kỳ để kiểm tra xem Dịch vụ A có phục hồi không.
- Nếu thời gian phản hồi trở lại bình thường, circuit sẽ chuyển sang trạng thái Bán Mở, cho phép các yêu cầu kiểm tra giới hạn. Nếu thành công, nó sẽ đặt lại về trạng thái Đóng.
Tại Sao Không Gọi Dịch Vụ Trực Tiếp?
Bạn có thể tự hỏi, "Tại sao không để các yêu cầu đến dịch vụ gặp sự cố và để nó thời gian chờ tự nhiên?" Dưới đây là lý do:
- Nếu mỗi yêu cầu chờ đợi một thời gian chờ 30 giây, tất cả các yêu cầu đến sẽ bị xếp hàng, tiêu tốn tài nguyên.
- Mô hình Circuit Breaker tránh điều này bằng cách thất bại nhanh khi một dịch vụ vượt quá ngưỡng thất bại, trả về lỗi cho consumer ngay lập tức.
- Điều này ngăn chặn việc hình thành hàng đợi và đảm bảo hệ thống vẫn phản hồi.
Khi Dịch vụ A phục hồi, circuit breaker sẽ mở lại giao thông, phục vụ các yêu cầu mới mà không xử lý backlog. Cách tiếp cận này hy sinh một vài yêu cầu để cứu toàn bộ hệ thống khỏi sụp đổ.
Tại Sao Thất Bại Nhanh Lại Tốt Hơn Cho Người Dùng
Từ quan điểm của người dùng, việc phải chờ đợi lâu để nhận phản hồi là điều rất khó chịu. Mô hình Circuit Breaker ưu tiên phản hồi nhanh - ngay cả khi đó là lỗi - hơn là để người dùng chờ đợi. Bằng cách cách ly các hỏng hóc, nó ngăn chặn các vấn đề lan truyền và đảm bảo hệ thống phục hồi nhanh chóng.
Kết Luận
Mô hình Circuit Breaker là một cứu cánh trong các hệ thống phân tán, đặc biệt là cho kiến trúc microservices. Bằng cách theo dõi tình trạng dịch vụ, thất bại nhanh và ngăn ngừa việc tiêu tốn tài nguyên, nó giữ cho hệ thống của bạn bền bỉ và người dùng của bạn hài lòng.
Các Thực Hành Tốt Nhất
- Luôn thiết lập ngưỡng hợp lý cho circuit breaker để tránh việc quá nhiều yêu cầu bị từ chối.
- Đảm bảo thực hiện kiểm tra thường xuyên tình trạng của các dịch vụ.
Những Cạm Bẫy Thường Gặp
- Không định nghĩa rõ ràng các điều kiện để mở và đóng circuit.
- Bỏ qua việc theo dõi và phân tích dữ liệu để điều chỉnh ngưỡng.
Mẹo Hiệu Suất
- Sử dụng caching để giảm tải cho các dịch vụ khi có nhiều yêu cầu.
- Tối ưu hóa các dịch vụ để giảm thời gian phản hồi.
Khắc Phục Sự Cố
- Nếu circuit luôn ở trạng thái Mở, xem xét lại ngưỡng và cải thiện dịch vụ.
- Theo dõi log để tìm ra nguyên nhân gốc rễ của sự cố.
Các Câu Hỏi Thường Gặp (FAQ)
1. Circuit Breaker có thể được áp dụng cho tất cả các dịch vụ không?
Có, circuit breaker có thể được áp dụng cho bất kỳ dịch vụ nào trong kiến trúc microservices để tăng tính ổn định.
2. Có cách nào khác để xử lý hỏng hóc không?
Có, các mẫu khác như Retry Pattern hay Fallback Pattern cũng có thể được áp dụng, nhưng Circuit Breaker thường là lựa chọn đầu tiên để xử lý hỏng hóc.