Nagłówek Retry-After: jak długo należy poczekać, zanim ponowisz próbę

Retry-After to nagłówek odpowiedzi HTTP, który informuje aplikację o tym, jak długo ma czekać przed wysłaniem następnego żądania. Wartość jest albo liczbą sekund, albo datą HTTP. Gdy interfejs API je wysyła, jest to najbardziej niezawodna odpowiedź na „kiedy mogę spróbować ponownie?”, ponieważ pochodzi z serwera, który odrzucił żądanie. Aby uzyskać więcej informacji, zobacz RFC 9110, sekcja 10.2.3.

Jak wygląda nagłówek Retry-After

Nagłówek ma 2 formaty. Aplikacja musi obsługiwać oba te elementy.

Format Example Co to znaczy
Seconds Retry-After: 120 Odczekaj 120 sekund (2 minuty) od momentu odebrania odpowiedzi. Wartość jest nieujemną liczbą całkowitą.
Data HTTP Retry-After: Fri, 31 Dec 1999 23:59:59 GMT Nie wysyłaj żądania ponownie przed upływem tego czasu. Data jest zawsze podawana w GMT.

Serwery wysyłają Retry-After z następującymi kodami stanu:

Status Co oznacza Retry-After Source
429 Too Many Requests Jak długo czekać przed wysłaniem nowego żądania. Serwer może go uwzględnić. RFC 6585, sekcja 4
503 Service Unavailable Jak długo oczekuje się, że usługa będzie niedostępna. Serwer może go uwzględnić. RFC 9110, sekcja 15.6.4
413 Content Too Large Jeśli stan jest tymczasowy, serwer powinien podać, po jakim czasie ustąpi. RFC 9110, sekcja 15.5.14
Dowolne 3xx przekierowanie Minimalny czas oczekiwania przed podążeniem za przekierowaniem. RFC 9110, sekcja 10.2.3

Nagłówek jest opcjonalny. Niektóre interfejsy API używają własnych nagłówków. Na przykład GitHub informuje o zresetowaniu limitu za pomocą x-ratelimit-reset. Aby uzyskać więcej informacji, zobacz Przekroczono limit wywołań API GitHub.

Jak obsłużyć Retry-After

  1. Odczytaj oba formaty. Jeśli wartość jest liczbą, oznacza sekundy. W przeciwnym razie przeanalizuj ją jako datę i odejmij bieżący czas. Jeśli data jest już w przeszłości, możesz ponowić próbę od razu.
  2. Poczekaj co najmniej tak długo, jak podano w nagłówku. Wcześniejsze ponowienie próby zwykle daje kolejny 429 lub 503. Niektóre interfejsy API nadal liczą żądania, gdy ograniczają liczbę twoich żądań, więc wczesne ponawianie prób może wydłużyć czas oczekiwania. Zobacz na przykład wskazówki dotyczące ograniczania przepustowości Microsoft Graph.
  3. Zastosuj mechanizm ponawiania z losowym opóźnieniem, gdy brakuje nagłówka. Dwukrotnie zaczekaj po każdej nieudanej próbie, dodaj losową wartość, aby wielu klientów nie ponawiało próby w tym samym momencie, i ogranicz czas oczekiwania.
  4. Ogranicz liczbę prób. Po kilku próbach zwróć błąd do wywołującego.
  5. Sprawdź, czy ponawianie próby może pomóc. Niektóre interfejsy API zwracają 429, gdy wykorzystasz środki lub wyczerpiesz limit wydatków. Oczekiwanie nie rozwiąże tych problemów. Aby zapoznać się z przykładem, zobacz OpenAI insufficient_quota i credit_balance_exhausted.
function retryDelayMs(response, attempt) {
  const value = response.headers.get('retry-after');
  if (value) {
    const seconds = Number(value);
    const ms = Number.isNaN(seconds) ? Date.parse(value) - Date.now() : seconds * 1000;
    if (!Number.isNaN(ms)) {
      return Math.max(ms, 0);
    }
  }
  // No usable header: exponential backoff with jitter, capped at 30 seconds
  return Math.random() * Math.min(30_000, 1_000 * 2 ** attempt);
}

Wiele zestawów SDK obsługuje Retry-After dla Ciebie, ale tylko do momentu, aż zabraknie ponownych prób. Wtedy w kodzie pojawia się błąd.

SDK Co robi domyślnie
standardowy moduł obsługi odporności platformy .NET Ponawia próbę odpowiedzi o kodach 408, 429 i 5xx do 3 razy z wykładniczo rosnącym opóźnieniem i losowym odchyleniem. Używa Retry-After dla opóźnienia, ponieważ ShouldRetryAfterHeader domyślnie ma wartość true.
Zestawy SDK Microsoft Graph Użyj Retry-After, gdy jest obecny, i wróć do algorytmu wykładniczego ponawiania, gdy go nie ma. Żądania wewnątrz partii JSON nie są automatycznie ponawiane.
Pakiet SDK OpenAI dla Pythona Ponawia próby przy błędach połączenia oraz odpowiedziach 408, 409, 429 i 5xx 2 razy z krótkim opóźnieniem wykładniczym. Ustaw max_retries, aby to zmienić.

Sprawdź dokumentację zestawu SDK, aby uzyskać dokładne zasady, i przetestuj, co się stanie po ostatnim ponowieniu próby.

Jak przetestować, czy aplikacja obsługuje Retry-After

Rzadko dostajesz Retry-After podczas programowania, a kiedy już tak się stanie, nie możesz kontrolować jego wartości. Dlatego sposób testowania decyduje o tym, czy znajdziesz usterki, zanim zrobią to użytkownicy.

Approach Co znajdziesz To, co przegapisz
Poczekaj na produkcję Rzeczywiste awarie Wszystko, dopóki użytkownik tego nie kliknie
Zamockuj interfejs API w testach lub pozwól agentowi programistycznemu napisać mock Czy kod analizuje nagłówek Czy rzeczywisty klient HTTP lub zestaw SDK czeka wystarczająco długo i co interfejs API naprawdę wysyła. Aplikacja wymaga również przełącznika tylko do testów, aby połączyć się z mockiem.
Wywołuj rzeczywiste API, dopóki API nie zacznie ograniczać żądań Faktyczne zachowanie Nie można wyzwolić odpowiedzi ograniczonej na żądanie i wykorzystujesz swój rzeczywisty limit przydziału
Przechwytywanie rzeczywistego ruchu aplikacji i zwracanie odpowiedzi z ograniczoną przepustowością na żądanie Czy rzeczywisty zestaw SDK i zasady ponawiania prób czekają tak długo, jak podano w nagłówku Nic się nie zmienia w aplikacji, więc nie testuje twojego kodu w izolacji. Zachowaj testy jednostkowe do tego.

Wypróbuj ją w swojej aplikacji

Dev Proxy przechwytuje żądania aplikacji do wybieranych interfejsów API i zwraca 429 odpowiedzi z nagłówkiem Retry-After, podczas gdy aplikacja nadal wywołuje rzeczywiste adresy URL. RetryAfterPlugin zapamiętuje, kiedy można ponowić każde ograniczone żądanie. Jeśli aplikacja wywołuje ten sam adres URL przed tym czasem, Dev Proxy zgłasza to i ponownie ogranicza żądanie. Wtyczka śledzi 429 tylko odpowiedzi.

W pliku błędów dla GenericRandomErrorPlugin ustaw Retry-After wartość 429 odpowiedzi na @dynamic, a Dev Proxy wypełnia liczbę sekund i śledzi ją za Ciebie.

Aby go wypróbować, pobierz ustawienie wstępne, które używa obu wtyczek, i uruchom Dev Proxy za jego pomocą:

devproxy config get openai-throttling
devproxy --config-file "~dataFolder/configs/openai-throttling/.devproxy/devproxyrc.json"

Następnie uruchom aplikację jak zwykle i obserwuj, co robi. Aby zainstalować Dev Proxy, zobacz Set up Dev Proxy.

Następne kroki

Informacje dodatkowe