Làm thế nào để tránh cơn bão thử lại trên mạng trong các dịch vụ phân tán?


10

"Cơn bão thử lại" xảy ra khi các máy khách được cấu hình để thử lại số lần đã đặt trước khi từ bỏ, chính sách thử lại là cần thiết vì mất gói sẽ xảy ra trong hoạt động bình thường của dịch vụ.

Lấy ví dụ này:

Kiến trúc mẫu

Ví dụ, nếu toàn bộ các dịch vụ được thu nhỏ để hỗ trợ 80.000 yêu cầu mỗi giây và chạy với khoảng 80% công suất, lưu lượng truy cập tăng đột biến khiến dịch vụ nhận 101.000 yêu cầu mỗi giây sẽ khiến 1.000 yêu cầu đó không thành công.

Khi các chính sách thử lại bắt đầu, bạn kết thúc với hơn 1000 yêu cầu, tùy thuộc vào nơi phát hiện lỗi sẽ đẩy toàn bộ dịch vụ lên tới 102.000 yêu cầu mỗi giây - từ đó dịch vụ của bạn đi vào vòng xoáy tử thần nhân đôi số yêu cầu thất bại mỗi giây.

Khác với việc cung cấp quá nhiều dịch vụ vượt quá giao dịch cao điểm dự kiến, sẽ không hiệu quả. Những chiến lược nào bạn có thể sử dụng để tránh "cơn bão thử lại"?


Nếu 100kQPS là 80% công suất, thì 101kQPS sẽ không dẫn đến thất bại 1k, điều đó sẽ dẫn đến thất bại bằng 0 - đó có phải là điểm của việc cung cấp quá mức không?
Adrian

@Adrian quyền của bạn, đó là một ví dụ giả định để giải thích vấn đề - Tôi đã cố gắng rút gọn đủ để làm rõ quan điểm của mình mà không quá trừu tượng. Tôi đã sửa "tỷ lệ để hỗ trợ 100.000" thành "tỷ lệ để hỗ trợ 80.000".
Richard Slater

Câu trả lời:


7

Nó phụ thuộc vào những gì bạn đang cố gắng tránh.

Nếu bạn đang cố gắng tránh bất kỳ sự can thiệp dịch vụ nào của một dịch vụ thực sự quan trọng (tôi nghĩ theo nghĩa "mọi người sẽ chết nếu cuộc gọi API của tôi không được phục vụ một cách thích hợp"), bạn chỉ cần ngân sách cho sự thiếu hiệu quả rất lớn mà đến từ rất nhiều cung cấp tài nguyên chuyên dụng. Và vâng, họ phải tận tâm, không ai trong số này cho phép tăng lưu lượng truy cập, nhiều dịch vụ tăng vọt sẽ gây ra sự cố ngừng hoạt động.

Trong trường hợp rất có thể là dịch vụ của bạn đi xuống sẽ bất tiện, bạn có thể giải quyết vấn đề cả từ phía máy khách và máy chủ. Mặc dù đáng lưu ý rằng thực sự không thể giải quyết vấn đề về lưu lượng truy cập nhiều vì không xử lý lưu lượng (tiêu tốn tài nguyên), bạn không thể biết nếu đó là thử lại, nếu thử lại yêu cầu thành công nhưng xử lý sai bởi khách hàng, nếu đó là DDOS, v.v. Nhưng bạn có thể giảm thiểu tác động.

Trong mã máy khách, hãy viết logic thử lại hợp lý có giới hạn trên và cơ chế cho sự thất bại một cách duyên dáng. Bằng cách đó, bạn không gắn bó người dùng của mình trong một vòng lặp vô hạn của các yêu cầu không thành công và bạn chỉ báo lỗi cho họ để thử bất cứ điều gì họ vừa làm trong thời gian ngắn.

Đối với cơ sở hạ tầng phía máy chủ của bạn, giải pháp đơn giản nhất là điều tiết. Giới hạn cứng đối với các yêu cầu, đặc biệt là nếu bạn có thể thử và truyền bá chúng một cách hợp lý dựa trên trường hợp sử dụng cụ thể của bạn (ví dụ: Nếu bạn có một dịch vụ tập trung đưa ra một số quyết định khó khăn, bạn có muốn bắt đầu chặn các yêu cầu xa về mặt địa lý có thể dẫn đến việc treo các luồng Phía máy chủ? Hay bạn muốn phân phối sự cố ngừng hoạt động nhỏ nhưng không thể tránh khỏi của mình một cách đồng đều? v.v.) Về cơ bản, thực tế là việc trả lại 503 một cách cố ý từ một cổng là một địa ngục rẻ hơn rất nhiều so với việc để yêu cầu đi qua và gửi 504 dù sao. Về cơ bản buộc khách hàng hành xử dựa trên những gì bạn hiện có thể cung cấp và cung cấp phản hồi chính xác để khách hàng có thể phản ứng phù hợp.


5

Một cách để ngăn chặn những cơn bão thử lại này là sử dụng các cơ chế dự phòng.

Từ phần Thực hiện dự phòng trên phần thử lại của Google App Engine Designing for Scale :

Mã của bạn có thể thử lại thất bại, cho dù gọi một dịch vụ như Cloud Datastore hoặc dịch vụ bên ngoài bằng cách sử dụng URL Fetch hoặc API API. Trong những trường hợp này, bạn phải luôn luôn thực hiện chính sách dự phòng theo cấp số nhân ngẫu nhiên để tránh vấn đề bầy đàn . Bạn cũng nên giới hạn tổng số lần thử lại và xử lý các lỗi sau khi đạt đến giới hạn thử lại tối đa.

Hầu hết các API GAE đã có các cơ chế / chính sách dự phòng như vậy được bật theo mặc định.


Cảm ơn, thực hiện các cơ chế backoff là lời khuyên tuyệt vời, tôi thường sử dụng backoff theo cấp số nhân có thể định cấu hình bằng cách sử dụng Khối ứng dụng Xử lý lỗi thoáng qua . Tuy nhiên, qua hơn 5 năm kinh nghiệm vận hành vận hành các ứng dụng siêu quy mô trong Azure, ngay cả khi có sự lùi lại theo cấp số nhân, "cơn bão thử lại" vẫn xảy ra khá thường xuyên - tôi chưa bao giờ có thể tìm ra chiến lược khả thi để tránh chúng.
Richard Slater
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.