Przekroczono limit liczby żądań interfejsu API GitHub: co to znaczy i jak sobie z tym poradzić

GitHub ogranicza liczbę żądań interfejsu API REST, które może wysyłać aplikacja. Po przekroczeniu limitu GitHub odrzuca żądania ze statusem 403 lub 429, dopóki limit nie zostanie zresetowany lub nie upłynie czas oczekiwania. GitHub ma 2 rodzaje limitów: podstawowy limit żądań na godzinę i limity pomocnicze, które chronią przed gwałtownymi seriami żądań. Jeśli aplikacja nadal wysyła żądania, gdy jest objęta limitem szybkości, GitHub może zablokować integrację. Aby uzyskać więcej informacji, zobacz Limity szybkości dla interfejsu API REST.

Jak wyglądają limity szybkości żądań w GitHubie

Limit Wartość Kiedy to przejrzysz
Podstawowy, nieuwierzytelniony 60 żądań na godzinę, na adres IP 403 lub 429, i x-ratelimit-remaining jest 0
Podstawowy, osobisty token dostępu 5000 żądań na godzinę Tak samo jak powyżej
Podstawowy, GITHUB_TOKEN w GitHub Actions 1000 żądań na godzinę, na repozytorium Tak samo jak powyżej
Secondary Na przykład nie więcej niż 100 współbieżnych żądań, 900 punktów na minutę dla punktów końcowych REST i około 80 żądań generujących zawartość na minutę 403 lub 429 z komunikatem o błędzie. retry-after może występować.

GitHub może zmienić limity pomocnicze bez powiadomienia i nie ma możliwości sprawdzenia, jak bardzo zbliżasz się do tych limitów.

Każda odpowiedź zawiera nagłówki, które informują o tym, gdzie znajdujesz się w limicie podstawowym:

Header Co ci to mówi
x-ratelimit-limit Maksymalna liczba żądań na godzinę
x-ratelimit-remaining Ile żądań pozostało w bieżącym oknie
x-ratelimit-used Ile żądań wysłano w bieżącym oknie
x-ratelimit-reset Gdy okno zostanie zresetowane, w sekundach epoki UTC
x-ratelimit-resource Do którego limitu zaliczono żądanie

Jak obsłużyć limit żądań GitHub

  1. Odróżnij ograniczenie liczby żądań od błędu uprawnień. GitHub również zwraca 403, gdy token nie ma uprawnień dostępu. Jeśli odpowiedź nie retry-afterma wartości , nie 0ma wartości , x-ratelimit-remaining a komunikat nie wspomina o limicie szybkości, jest to problem z uprawnieniami. Nie ponawiaj próby.
  2. Najpierw postępuj za retry-after. Jeśli nagłówek jest obecny, odczekaj tyle sekund.
  3. W przeciwnym razie zaczekaj na zresetowanie. Jeśli x-ratelimit-remaining parametr ma wartość 0, nie ponawiaj próby do czasu w pliku x-ratelimit-reset.
  4. W przeciwnym razie zaczekaj co najmniej 1 minutę. W przypadku limitu pomocniczego bez żadnego z nagłówków GitHub prosi o odczekanie co najmniej 1 minuty i poczekanie dłużej po każdym nieudanym ponowieniu próby. Zatrzymaj się po określonej liczbie ponownych prób i zgłoś błąd.
  5. Zwolnij, zanim wyczerpiesz limit. Użyj polecenia x-ratelimit-remaining i x-ratelimit-reset, aby kontrolować tempo żądań. Nie twórz logiki wokół dokładnej pozostałej liczby, ponieważ GitHub może zmieniać limity. Nagłówki x-ratelimit-* są źródłem prawdy, a nie GET /rate_limit punktem końcowym.
async function githubWaitMs(response, attempt) {
  if (response.status !== 403 && response.status !== 429) {
    return null;
  }
  const retryAfter = response.headers.get('retry-after');
  if (retryAfter) {
    return Number(retryAfter) * 1000;
  }
  if (response.headers.get('x-ratelimit-remaining') === '0') {
    const resetMs = Number(response.headers.get('x-ratelimit-reset')) * 1000;
    return Math.max(resetMs - Date.now(), 0);
  }
  const { message = '' } = await response.clone().json().catch(() => ({}));
  if (response.status === 429 || /rate limit/i.test(message)) {
    return 60_000 * 2 ** attempt;
  }
  // A 403 without rate limit signals is a permission problem: don't retry
  return null;
}

Obiekt wywołujący ponawia próbę, gdy funkcja zwraca liczbę i zatrzymuje się po kilku próbach.

Jak przetestować, czy aplikacja obsługuje limity szybkości żądań GitHub

Rzadko osiągasz limit szybkości GitHub podczas opracowywania. Wysyłasz kilka żądań, a limit 5000 na godzinę wydaje się nie mieć końca. Dlatego sposób testowania obsługi limitów szybkości decyduje, czy znajdziesz usterki przed wykonaniem czynności przez użytkowników.

Approach Co znajdziesz Czego przegapisz
Poczekaj na produkcję Rzeczywiste awarie Wszystko, dopóki użytkownik tego nie kliknie
Mockuj interfejs API w testach lub pozwól agentowi programistycznemu napisać mock Czy gałąź ponowienia jest uruchamiana Rzeczywiste nagłówki i treści błędów GitHub oraz zasady ponawiania prób w Twoim SDK. Aplikacja wymaga również przełącznika tylko do testowania, aby połączyć się z mockiem.
Wywołuj rzeczywiste API, aż nałoży limit Rzeczywiste zachowanie Wymaga to nawet 5000 żądań, nie można wywołać limitu wtórnego w dowolnym momencie i ryzykujesz zablokowanie integracji
Przechwytuj rzeczywisty ruch aplikacji i zwracaj na żądanie odpowiedzi o limicie żądań Rzeczywiste adresy URL, rzeczywisty SDK i polityka ponawiania prób oraz własne nagłówki i format błędów GitHuba Nic się nie zmienia w aplikacji, więc nie testuje Twojego kodu w izolacji. Zachowaj testy jednostkowe dla tego celu.

Wypróbuj ją w aplikacji

Serwer proxy deweloperów przechwytuje żądania aplikacji i api.github.com zwraca odpowiedzi dotyczące limitu szybkości w stylu GitHub, podczas gdy aplikacja nadal wywołuje rzeczywiste adresy URL. Ustawienie github-rate-limiting wstępne zlicza żądania do limitu 60 na godzinę, wysyła x-ratelimit-* nagłówki i zwraca wartość z wartością 429API rate limit exceeded , gdy zabraknie czasu. Do tego czasu żądania również przechodzą do GitHub i liczą się z rzeczywistym limitem.

Pobierz preset i uruchom Dev Proxy za jego pomocą:

devproxy config get github-rate-limiting
devproxy --config-file "~dataFolder/configs/github-rate-limiting/.devproxy/devproxyrc.json"

Aby przetestować limity pomocnicze, należy zamiast tego uruchomić Dev Proxy z devproxyrc-secondary.json w tym samym folderze. Losowo zwraca pomocniczy limit żądań 429 z nagłówkiem retry-after.

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

Następne kroki

Informacje dodatkowe