Lợi nhuận:
- Có thể diễn giải giới hạn tốc độ (RPM/ITPM/OTPM) và 429 lỗi
- Triển khai thời gian chờ theo cấp số nhân và thử lại với tính năng thử lại sau
- Phân loại và xử lý chính xác các mã lỗi HTTP phổ biến (400/401/429/500/529)
Trong môi trường sản xuất, không có API nào luôn phản hồi hoàn hảo. Đôi khi bạn gửi yêu cầu quá nhanh và đạt đến giới hạn; đôi khi máy chủ tạm thời bận; Đôi khi yêu cầu của bạn sai ngay từ đầu. Điều phân biệt sự tích hợp vững chắc với nỗ lực nghiệp dư là nó xử lý các tình huống này một cách có tính dự đoán và tự động. Trong phần này, bạn sẽ tìm hiểu về giới hạn tốc độ (RPM/ITPM/OTPM), lỗi 429, thử lại với thời gian đợi lũy thừa và phân loại thích hợp các mã lỗi HTTP phổ biến. Mục tiêu: xây dựng một quy trình mạnh mẽ đến mức người dùng sẽ không bao giờ nhận thấy nó.
Giới hạn tốc độ là gì?
Nhà cung cấp giới hạn số lượng công việc mà một switch có thể thực hiện trong một khoảng thời gian nhất định. Sự bảo vệ này; Nó bảo vệ cả cơ sở hạ tầng và bạn khỏi sự bùng nổ chi phí đột ngột. Có ba loại giới hạn phổ biến:
- RPM (Yêu cầu mỗi phút): Số lượng yêu cầu mỗi phút.
- ITPM (Mã thông báo đầu vào mỗi phút): Mã thông báo đầu vào có thể được xử lý mỗi phút.
- OTPM (Mã thông báo đầu ra mỗi phút): Mã thông báo đầu ra có thể được tạo ra mỗi phút.
Nếu bạn vượt quá bất kỳ giới hạn nào trong số này, nhà cung cấp sẽ từ chối yêu cầu và trả về mã lỗi 429. Giới hạn thường khác nhau tùy thuộc vào cấp độ (cấp) tài khoản của bạn và có thể tăng lên theo thời gian.
Mẹo: Bạn có thể xem khi nào bạn sắp đạt đến giới hạn từ tiêu đề phản hồi. Hầu hết các nhà cung cấp báo cáo hạn ngạch còn lại của bạn với các tiêu đề như x-ratelimit-remaining-*. Giám sát các giá trị này và điều tiết lưu lượng truy cập phía trước là cách hoàn hảo nhất để ngăn chặn sự cố mà không gặp phải 429.
429 và thoái lui theo hàm mũ
429 (giới hạn tốc độ) là lỗi tạm thời và có thể thử lại. Phản hồi đúng là đợi yêu cầu một lúc rồi thử lại. Nhưng chờ đợi liên tục vẫn chưa đủ; Nếu mọi người thử lại cùng một lúc, giới hạn sẽ lại đạt được. Giải pháp là rút lui theo cấp số nhân: tăng thời gian chờ đợi theo cấp số nhân với mỗi lần thử thất bại.
# Thử nghiệm logic backoff theo cấp số nhân 1 → 429 → đợi 1 giây thử nghiệm 2 → 429 → đợi 2 giây thử nghiệm 3 → 429 → đợi 4 giây thử nghiệm 4 → 429 → đợi 8 giây (+ "jitter ngẫu nhiên nhỏ")... bỏ cuộc và báo cáo sau tối đa N thử nghiệm
Việc thêm một chút ngẫu nhiên (jitter) vào điều này sẽ ngăn các yêu cầu xung đột khi cố gắng thử lại cùng lúc. Ngoài ra, phản hồi 429 thường mang tiêu đề `thử lại sau`: "thử lại sau vài giây". Tôn trọng danh hiệu này thì đúng hơn là mù quáng chờ đợi.
Thận trọng: Khi bạn nhận được 429, việc "ép buộc bằng cách gửi thêm yêu cầu" sẽ khiến tình hình trở nên tồi tệ hơn; Giới hạn tiếp tục được lấp đầy và không có yêu cầu nào được thực hiện. Phản ứng đúng là rút lui chứ không phải tăng tốc. Tin vui: hầu hết các SDK chính thức đều tự động thử lại 429 và lỗi máy chủ bị trì hoãn — hãy sử dụng hành vi này của SDK trước khi cài đặt thủ công.
Phân loại mã lỗi HTTP
Không phải mọi sai lầm đều giống nhau. Sự khác biệt quan trọng: nó có thể được thử lại hay đó là vấn đề về yêu cầu/danh tính?
Mã
Ý nghĩa
Có thể thử lại được không?
phản hồi đúng
400
Yêu cầu không hợp lệ (lỗi định dạng/tham số)
không
Sửa yêu cầu; đừng gửi lại lần nữa
401
Lỗi xác thực (khóa không hợp lệ/thiếu)
không
Sửa khóa/tiêu đề
403
Không có ủy quyền (không có quyền truy cập vào mô hình/tính năng)
không
Kiểm tra quyền/phạm vi
404
Không tìm thấy (ID mô hình/điểm cuối không chính xác)
không
ID/địa chỉ mẫu máy chính xác
429
Đã vượt quá giới hạn tốc độ
Có
Rút lui + thử lại sau
500
Lỗi máy chủ
Có
Hãy thử lại bằng cách rút lui
529
Máy chủ quá tải
Có
Hãy thử lại bằng cách rút lui
Quy tắc vàng: 429, 500 và 529 là tạm thời; Nó được thử lại bằng cách rút tiền. 400, 401, 403, 404 là các vấn đề về yêu cầu/danh tính; Cố gắng lại cũng không giải quyết được vấn đề và còn lãng phí công sức. Mã của bạn phải phân biệt giữa hai nhóm này.
Từng bước: Cuộc gọi bền vững
- Gửi yêu cầu. Nếu thành công, hãy tiếp tục.
- Phân loại mã lỗi. Có thể thử lại được không?
- Nếu có thể thử: thực hiện thử lại sau, áp dụng thời gian chờ theo cấp số nhân + jitter, thử một số lần giới hạn (ví dụ: tối đa 5 lần).
- Nếu chưa thử: Sửa (định dạng/khóa) và dừng; Đừng lặp lại cùng một yêu cầu sai lầm trong vòng lặp.
- Hãy cân nhắc việc từ bỏ. Nếu vẫn không thành công sau n lần thử, hãy hiển thị thông báo lịch sự cho người dùng và ghi lại sự kiện (đơn vị theo dõi 11).
# Cuộc gọi mạnh mẽ pseudo-codedene = 0repeat: phản hồi = request_at() nếu phản hồi.success: trả về phản hồi nếu phản hồi.code trong [429, 500, 529] và thử < 5: wait = retry_after ?? (2^thử giây + jitter) ngủ(chờ); thử += 1; git lại nếu phản hồi.code trong [400, 401, 403, 404]: save_error(response); return "yêu cầu phải được sửa" return "lỗi vĩnh viễn, thử lại sau"
# Phản hồi lịch sự cho người dùng (khi số lần thử lại đã hết) "Hiện tại tôi đang bận, tôi không thể xử lý yêu cầu của bạn. Hãy thử lại sớm hoặc tôi đã lưu yêu cầu của bạn, tôi sẽ liên hệ lại với bạn khi nó sẵn sàng."
Lời nhắc yếu / Lời nhắc mạnh (ở đây: thiết kế thông báo lỗi)
# YẾU (hiển thị lỗi thô cho người dùng)"Lỗi 429: rate_limit_error"
# MẠNH (thân thiện với người dùng, trấn an, gợi ý hành động) "Đã xảy ra tình trạng tắc nghẽn tạm thời trong hệ thống. Chúng tôi đã nhận được yêu cầu của bạn một cách an toàn và nó đang được thử lại tự động. Nếu kết quả không xuất hiện trong vòng vài giây, bạn có thể làm mới trang."
Việc tiết lộ lỗi kỹ thuật thô cho người dùng cuối vừa làm suy yếu lòng tin vừa có thể là một lỗ hổng bảo mật. Phân loại lỗi nội bộ và cung cấp cho người dùng thông báo bình tĩnh, hướng đến hành động; chỉ cần viết chi tiết kỹ thuật cho hồ sơ.
Ba hộp nhỏ
Trường hợp 1 – Thuyền đâm vào vụ nổ giao thông. Một bot dịch vụ khách hàng đã nhận được 429 lượt truy cập tăng vọt vào ngày chiến dịch; Không có lần thử lại trong mã, mọi lỗi đều được phản ánh trực tiếp đến người dùng dưới dạng "lỗi". Họ đã thêm thoái lui theo cấp số nhân + thử lại sau; với cùng một lưu lượng truy cập, các yêu cầu được chuyển đi với độ trễ vài giây, người dùng không thấy bất kỳ lỗi nào.
Trường hợp 2 - Thử 400 trong vòng lặp. Một quá trình tích hợp đang gặp lỗi 404 do ID mô hình không hợp lệ nhưng lại coi tất cả các lỗi là "tạm thời" và thử lại trong một vòng lặp vô hạn; Nhật ký bị phồng lên và tạo ra tải trọng không cần thiết. Họ đã thêm phân loại lỗi: 404 được coi là vĩnh viễn, vòng lặp bị dừng và ID mẫu được sửa. Bài học: đừng thử lại mọi sai lầm.
Trường hợp 3 - Quản lý giới hạn từ phía trước. Công việc làm giàu dữ liệu liên tục chạy ở giới hạn 429. Họ đi theo tiêu đề còn lại x-ratelimit và điều tiết lưu lượng truy cập theo hạn ngạch. Vì vậy, họ giữ tốc độ ổn định ngay dưới mức giới hạn mà không mất bất kỳ 429 giây nào; Công việc được thực hiện dễ dàng hơn và nhanh hơn.
Những lỗi thường gặp
- Tăng tốc độ ở 429: Khiến tình hình trở nên tồi tệ hơn; Chuyển sang rút lui.
- Thử lại từng lỗi: 400/401/404 là vĩnh viễn; Cố gắng lại là một sự lãng phí.
- Sử dụng chờ cố định: Tạo xung đột; Sử dụng hàm mũ + jitter.
- Bỏ qua “retry-after”: Tuân thủ thời gian do nhà cung cấp quy định là chính xác nhất.
- Tiết lộ lỗi thô cho người dùng: Làm lung lay niềm tin, tạo lỗ hổng; Phân loại bên trong.
- Số lần thử lại không giới hạn: Đặt giới hạn trên (ví dụ: 5 lần thử lại); rồi từ bỏ một cách duyên dáng.
Tìm hiểu sâu hơn: Xếp hàng, Đồng thời và Ngắt mạch
Chịu đựng một ham muốn duy nhất là bước đầu tiên; Sự trưởng thành thực sự là quản lý số lượng lớn yêu cầu mà không đạt đến giới hạn. Ba khái niệm được áp dụng ở đây.
Hàng đợi: Bạn đặt các yêu cầu vào hàng đợi để gửi chúng với tốc độ được kiểm soát thay vì ngay lập tức. Việc xếp hàng giúp giải quyết các đợt bùng phát lưu lượng truy cập đột ngột: Ngay cả khi 1.000 yêu cầu đến cùng một lúc, hàng đợi sẽ giải phóng chúng với tốc độ dưới mức giới hạn. Bằng cách này bạn ngăn chặn được 429, sau đó bạn không phải lo lắng về việc sửa nó.
Giới hạn đồng thời: Bạn giới hạn số lượng yêu cầu "được gửi" cùng một lúc. Yêu cầu song song không giới hạn nhanh chóng lấp đầy giới hạn RPM và TPM. Mức trần đồng thời hợp lý (ví dụ: không quá 10 yêu cầu đồng thời) vừa duy trì các giới hạn vừa giúp hệ thống có thể dự đoán được.
Ngắt mạch: Nếu nhà cung cấp liên tục trả về 500/529, thay vì kiên trì thử mọi yêu cầu, bạn "ngắt mạch" một lúc và nhanh chóng thực hiện yêu cầu mà không bao giờ gửi được. Sau một thời gian chờ đợi, bạn bật lại mạch và thử. Mẫu này ngăn hệ thống của bạn gặp sự cố trong trường hợp nhà cung cấp tạm thời bị lỗi.
Cùng với nhau, ba điều này thiết lập khả năng phục hồi ở cấp hệ thống vượt quá logic thử lại của một cuộc gọi duy nhất. Ở quy mô nhỏ, việc thử lại tự động của SDK là đủ; Khi quy mô tăng lên, việc xếp hàng, xử lý đồng thời và ngắt mạch trở nên không thể thiếu. Tất cả đều có cùng một mục tiêu: phản ánh sự cố tạm thời cho người dùng không phải là sự cố mà là độ trễ vô hình trong vài giây.
Tóm lại
429 trả về khi vượt quá giới hạn tốc độ (RPM/ITPM/OTPM); Đây là lỗi tạm thời và sẽ được thử lại bằng cách sử dụng phương pháp thử lại sau và thời gian chờ lũy thừa + jitter. 500 và 529 cũng là tạm thời; 400/401/403/404 là vấn đề về yêu cầu/danh tính và không thể giải quyết bằng cách thử lại. Một luồng mạnh mẽ sẽ phân tách các lỗi thành hai nhóm này, thử với số lần giới hạn, giám sát giới hạn từ phía trước và hiển thị thông báo bình tĩnh cho người dùng.
Nhiệm vụ ứng dụng
Hãy xem xét sự tích hợp của bạn. (1) Liệt kê các mã lỗi bạn có thể gặp phải và tách chúng thành "có thể thử lại/vĩnh viễn". (2) Viết ra kế hoạch pullback theo cấp số nhân của bạn (giữ ban đầu, hệ số, giới hạn, jitter). (3) Chỉ định cách sử dụng tiêu đề thử lại sau. (4) Viết thông báo lịch sự để hiển thị cho người dùng khi hết số lần thử lại.
danh sách kiểm tra
- [ ] Tôi có thể giải thích các giới hạn RPM/ITPM/OTPM và 429.
- [ ] Tôi có thể áp dụng logic rút lui theo cấp số nhân + jitter + thử lại sau.
- [ ] Tôi có thể phân loại mã lỗi là có thể thử lại/vĩnh viễn.
- [ ] Tôi biết rằng chúng ta không nên thử mọi sai lầm.
- [ ] Thay vì một lỗi thô, tôi có thể hiển thị cho người dùng một thông báo bình tĩnh, hướng đến hành động.