Pitfalls and Patterns in Microservice Dependency Management
Bài tóm tắt Google 2021 4. Điều chỉnh Độ khó: Trung bình
Google · 2021 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc
Bài trên InfoQ của Silvia Esparrachiari (Google, 11 năm; Google Cloud SRE) và Betsy Beyer, viết lại từ talk QCon Plus. Theo tác giả, đây là kinh nghiệm cá nhân, không mô tả một sản phẩm cụ thể của Google; các tình huống dùng sản phẩm hư cấu "PetPic". Mọi nhận định dưới đây là theo tác giả.
Bối cảnh
- Lộ trình chung: một binary → nhân bản ở nhiều vùng → tách thành microservice (API, Auth, Control, Data, Ops) giao tiếp qua mạng → một phần chạy trên cloud. Mạng trở thành một phần của sản phẩm.
- PetPic phục vụ hai vùng (Happytails, Furland), mỗi vùng 100 khách; frontend API riêng từng vùng, database dùng chung một vùng toàn cục.
Ba tình huống
1. Tăng trưởng không đồng đều
- Ra tính năng ảnh mèo ở Happytails trước: khách tăng 10%, tải DB tăng 10%. Chuẩn bị y hệt cho Furland (thêm 10% DB).
- Ở Furland, tải DB tăng 60% mà không có thêm khách nào: khách Furland vốn thích mèo, giờ dùng nhiều hơn hẳn. DB lên 80%, lỗi 500, phải rollback; thêm CPU cho DB không xong trong ngày.
- Bài học: tăng số khách khác với tăng mức tương tác; hành vi khác nhau theo vùng. Thử nghiệm ở mọi vùng, và cho backend đủ thời gian cấp tài nguyên (mua máy, lắp đặt).
2. Cô lập lỗi
- DB toàn cục là điểm hỏng chung: thay đổi ở vùng này làm hỏng vùng kia.
- Cache cục bộ có giới hạn ở từng vùng: giảm latency và tải DB, kích thước theo traffic vùng, và trả dữ liệu cũ khi backend hỏng (xuống cấp nhẹ nhàng). Đổi lại: độ tươi, nhất quán giữa các cache; service không được phụ thuộc vào cache mới phục vụ được.
- Thành phần Control (kiểm duyệt ảnh bằng ML) giới hạn 500/1.000 thread cho việc kiểm duyệt, nhưng một khách tải ảnh hàng loạt làm 500 thread đó ăn hết CPU và RAM, cả hai vùng chậm. Cách sửa: mỗi vùng một instance Control riêng.
- Theo tác giả: chạy trên cloud nhiều vùng không tự động là cô lập; một service nhiều vùng vẫn có thể hành xử như service toàn cục. Service stateless dễ cô lập; DB khó hơn, có thể đọc cục bộ qua cache và chấp nhận nhất quán chậm giữa vùng.
3. Lập SLO
- SLO bên ngoài phải tính từ SLO của mọi backend và mọi hành trình người dùng. Ops ghi bất đồng bộ nên bỏ khỏi phép tính.
- Đọc: API 50 ms; nếu ít nhất nửa request trúng cache thì p50 = 100 ms là hợp lý; xấu nhất 50 + 10 (miss) + 100 (mạng) + 240 (DB) = 400 ms.
- Ghi: Control 150–800 ms, Data tới 1.000 ms → xấu nhất gần 2.000 ms, vượt xa SLO đã đề ra, vì người lập SLO quên tính trường hợp xấu. Chặn p99 bằng deadline thì lại sinh lỗi kiểu DB ghi xong sau khi API đã báo hết hạn.
Bài học cho SWE
- Đặt các thành phần của một stack cùng chỗ và cùng miền lỗi; phụ thuộc chéo vùng thì cần xuống cấp nhẹ nhàng (Độ tin cậy và multi-region).
- Microservices cho phép cô lập lỗi, nhưng chỉ khi kiến trúc chủ động cắt miền lỗi (Monolith và microservices — đi và quay lại).
- Cache cục bộ vừa là công cụ hiệu năng vừa là lớp đệm khi backend hỏng (Cache và invalidation).
Liên quan
Được nhắc tới trong
Chủ đề (3)
Công ty (1)
Bài tóm tắt (1)