Timeout — luôn đặt, và đặt giảm dần theo chiều sâu chuỗi gọi.
- Không client HTTP nào nên chạy với timeout mặc định vô hạn; một downstream treo sẽ giữ hết connection pool và lan lỗi ngược lên.
- Đặt theo percentile thực đo (vd p99 + biên), không đặt số tròn cảm tính.
- Dùng deadline propagation: request vào gateway có ngân sách 3s thì service A gọi B chỉ được cấp phần còn lại (3s - thời gian đã tiêu), không phải 3s mới. Nếu ngân sách đã hết thì fail ngay, đừng gọi tiếp.
Retry — chỉ khi an toàn.
- Chỉ tự retry method idempotent (GET, PUT, DELETE) hoặc POST có idempotency key. Retry một POST trần khi timeout là nguồn của giao dịch trùng, vì timeout không nói cho ta biết server đã xử lý hay chưa.
- Chỉ retry lỗi tạm thời: lỗi kết nối, 502/503/504, 429. Không retry 4xx — request sai thì gọi lại vẫn sai.
- Backoff mũ + jitter ngẫu nhiên. Không jitter thì mọi client cùng retry một nhịp và tạo thundering herd, khiến service vừa hồi phục lại sập.
- Số lần retry nhỏ (2-3) và có retry budget toàn cục (vd retry không vượt 10% tổng request). Đây là điểm phân biệt câu trả lời khá và câu trả lời tốt.
- Tôn trọng Retry-After khi server đã nói rõ nên chờ bao lâu.
Cái bẫy lớn nhất: retry lồng nhau. Nếu mỗi tầng trong chuỗi A → B → C đều retry 3 lần thì một request gốc biến thành 27 request tới C. Chỉ retry ở một tầng (thường là tầng ngoài cùng hoặc tầng sát downstream), các tầng còn lại fail-fast.
Ghép với circuit breaker: khi tỉ lệ lỗi vượt ngưỡng thì mở mạch, trả lỗi ngay trong một khoảng, rồi thử half-open. Retry xử lý trục trặc thoáng qua; circuit breaker xử lý sự cố kéo dài — thiếu cái sau thì retry chỉ làm sự cố nặng thêm.