Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wskazówka
Nie znasz ograniczania przepustowości? Dowiedz się , czym jest ograniczanie przepustowości i jak go obsłużyć.
Na pierwszy rzut oka
Cel: Testowanie sposobu obsługi przez aplikację limitów liczby żądań interfejsu API REST GitHub
Czas: 15 minut
Plugins:RateLimitingPlugin, GenericRandomErrorPlugin, RetryAfterPlugin
Wymagania wstępne:konfigurowanie serwera proxy deweloperskiego
Aplikacja wywołuje interfejs API GitHub. Działa na Twojej maszynie, a potem zadanie CI, duża organizacja albo intensywny dzień sprawiają, że przekracza limit żądań i zaczyna kończyć się niepowodzeniem. Aby przetestować go względem rzeczywistego interfejsu API, musisz wyczerpać limit zapytań, a następnie poczekać do godziny, zanim będziesz mógł spróbować ponownie. Dev Proxy lokalnie symuluje limity liczby żądań GitHub, z limitem i przedziałem czasu, które wybierasz.
Dowiedz się, co zwraca GitHub
GitHub ma 2 rodzaje limitów liczby żądań dla interfejsu API REST.
Podstawowe limity szybkości ograniczają liczbę żądań wysyłanych na godzinę. Na przykład 60 dla nieuwierzytelnionych żądań i 5000 dla żądań z osobistym tokenem dostępu. Każda odpowiedź zawiera nagłówki pokazujące, gdzie jesteś:
| Header | Meaning |
|---|---|
x-ratelimit-limit |
Maksymalna liczba żądań na godzinę |
x-ratelimit-remaining |
Liczba żądań pozostawionych w bieżącym oknie |
x-ratelimit-reset |
Czas resetowania okna w sekundach epoki UTC |
Po przekroczeniu limitu podstawowego GitHub zwraca 403 lub 429, z ustawionym x-ratelimit-remaining na 0. Nie ponawiaj próby do czasu wskazanego w x-ratelimit-reset.
Pomocnicze limity szybkości chronią GitHub przed wybuchami, takimi jak zbyt wiele współbieżnych żądań lub zbyt duża ilość zawartości. Po przekroczeniu jednego z limitów GitHub zwraca 403 lub 429 z komunikatem o dodatkowym limicie szybkości. Jeśli odpowiedź ma retry-after nagłówek, poczekaj tyle sekund. W przeciwnym razie poczekaj co najmniej minutę i zwiększ czas oczekiwania, jeśli żądanie zakończy się niepowodzeniem.
GitHub mogą blokować integracje, które nadal wysyłają żądania, gdy są one ograniczone. Aby uzyskać więcej informacji, zobacz Limity szybkości interfejsu API REST w dokumentacji GitHub.
Symuluj podstawowy limit szybkości żądań
Użyj RateLimitingPlugin, aby zliczyć żądania i zwrócić nagłówki limitu szybkości GitHub. Aby przetestować bez oczekiwania na godzinę, użyj małego limitu i krótkiego okna.
Plik: devproxyrc.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "RetryAfterPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "RateLimitingPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "githubRateLimit"
}
],
"urlsToWatch": [
"https://api.github.com/*"
],
"githubRateLimit": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/ratelimitingplugin.schema.json",
"headerLimit": "x-ratelimit-limit",
"headerRemaining": "x-ratelimit-remaining",
"headerReset": "x-ratelimit-reset",
"resetFormat": "UtcEpochSeconds",
"costPerRequest": 1,
"rateLimit": 5,
"resetTimeWindowSeconds": 60,
"warningThresholdPercent": 0,
"whenLimitExceeded": "Custom",
"customResponseFile": "github-rate-limit-exceeded.json"
}
}
Caution
Dodaj element RetryAfterPlugin przed elementem RateLimitingPlugin w pliku konfiguracji. Jeśli dodasz to później, RateLimitingPlugin obsłuży żądanie, zanim RetryAfterPlugin będzie mógł to sprawdzić.
W pliku odpowiedzi niestandardowej zdefiniuj odpowiedź, którą GitHub zwraca po przekroczeniu podstawowego limitu szybkości.
Plik: github-rate-limit-exceeded.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/ratelimitingplugin.customresponsefile.schema.json",
"statusCode": 429,
"headers": [
{
"name": "content-type",
"value": "application/json; charset=utf-8"
}
],
"body": {
"message": "API rate limit exceeded for user ID 1.",
"documentation_url": "https://docs.github.com/rest/overview/rate-limits-for-the-rest-api"
}
}
Uruchom Dev Proxy i uruchom aplikację.
devproxy --config-file devproxyrc.json
Dev Proxy przekazuje pierwsze 5 żądań w każdej minucie do GitHub i ustawia nagłówki x-ratelimit-* w odpowiedziach. Od 6. żądania serwer proxy dewelopera zwraca odpowiedź o limicie szybkości z x-ratelimit-remaining ustawionym na 0 i x-ratelimit-reset ustawionym na koniec okna. Jeśli aplikacja ponownie wywołuje interfejs API przed zresetowaniem okna, RetryAfterPlugin zgłasza to i ogranicza żądanie.
Sprawdź, czy Twoja aplikacja:
- Odczytuje
x-ratelimit-remainingi spowalnia, zanim osiągnie0. - Zatrzymuje wywoływanie interfejsu API po odpowiedzi o przekroczeniu limitu żądań i czeka na
x-ratelimit-reset. - Informuje użytkownika o tym, co się dzieje, na przykład „osiągnięto limit żądań GitHub, ponawianie próby o godzinie 14:05”, zamiast kończyć się po cichu niepowodzeniem.
Note
GitHub zwraca wartość 403 lub 429 po przekroczeniu limitu liczby żądań. Aby przetestować, czy aplikacja obsługuje też 403, zmień wartość statusCode na 403. Tylko RetryAfterPlugin śledzi 429 odpowiedzi, więc nie zgłasza wczesnych ponownych prób po .403
Wskazówka
Serwer proxy deweloperów przekazuje żądania do GitHub do momentu osiągnięcia symulowanego limitu. Te żądania są również liczone względem rzeczywistego limitu szybkości GitHub.
Symulowanie limitów szybkości pomocniczej
Wtórne limity liczby żądań występują seriami i zawierają nagłówek retry-after. Użyj metody GenericRandomErrorPlugin , aby zwrócić je losowo.
Plik: devproxyrc.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "RetryAfterPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "GenericRandomErrorPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "githubSecondaryRateLimit"
}
],
"urlsToWatch": [
"https://api.github.com/*"
],
"githubSecondaryRateLimit": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.schema.json",
"errorsFile": "github-secondary-rate-limit.json",
"rate": 50,
"retryAfterInSeconds": 60
}
}
Plik: github-secondary-rate-limit.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.errorsfile.schema.json",
"errors": [
{
"request": {
"url": "https://api.github.com/*"
},
"responses": [
{
"statusCode": 429,
"headers": [
{
"name": "content-type",
"value": "application/json; charset=utf-8"
},
{
"name": "retry-after",
"value": "@dynamic"
}
],
"body": {
"message": "You have exceeded a secondary rate limit. Please wait a few minutes before you try again.",
"documentation_url": "https://docs.github.com/rest/overview/rate-limits-for-the-rest-api#about-secondary-rate-limits"
}
}
]
}
]
}
Uruchom serwer proxy deweloperów i uruchom aplikację. Sprawdź, czy aplikacja czeka przez liczbę sekund podaną w nagłówku retry-after, zanim ponownie wywoła interfejs API. Jeśli tak nie jest, RetryAfterPlugin to raportuje.
Jeśli używasz biblioteki Octokit z wtyczką ograniczania przepustowości, sprawdź, czy onRateLimit procedury obsługi i onSecondaryRateLimit procedury obsługi działają i że zwracają oczekiwany wynik.
Następny krok
Dowiedz się więcej o pliku RateLimitingPlugin.
Informacje dodatkowe
- Symulowanie odpowiedzi interfejsu API Rate-Limit — limity liczby żądań w dowolnym interfejsie API
- Przetestuj, czy moja aplikacja prawidłowo obsługuje ograniczanie przepustowości — ograniczanie przepustowości w dowolnym interfejsie API
- RetryAfterPlugin — weryfikowanie zachowania ponawiania prób
- Używaj Dev Proxy w CI/CD — automatyzuj testy odporności w swoim potoku