Test hoe uw app omgaat met GitHub API-frequentielimieten

Tip

Nieuw met throttling? Lees meer over throttling en hoe u hiermee omgaat.

In één oogopslag
Doel: Test hoe uw app omgaat met frequentielimieten van de GitHub REST API
Tijd: 15 minuten
Plugins:RateLimitingPlugin, GenericRandomErrorPlugin, RetryAfterPlugin
Vereisten:Dev Proxy instellen

Uw app roept de GitHub-API aan. Het werkt op uw computer, maar een CI-taak, een grote organisatie of een drukke dag duwt het over de ratelimiet en het begint te falen. Als u deze wilt testen op basis van de echte API, moet u uw ratelimiet opmaken en vervolgens maximaal een uur wachten voordat u het opnieuw kunt proberen. Dev Proxy simuleert GitHub-snelheidslimieten lokaal, met een limiet en een tijdvenster dat u kiest.

Weet wat GitHub retourneert

GitHub heeft twee soorten frequentielimieten voor de REST API.

Primaire aanvraaglimieten beperken het aantal aanvragen dat u per uur doet. Bijvoorbeeld 60 voor niet-geverifieerde verzoeken en 5000 voor verzoeken met een persoonlijk toegangstoken. Elk antwoord bevat headers die aangeven waar u bent:

Header Meaning
x-ratelimit-limit Het maximum aantal aanvragen per uur
x-ratelimit-remaining Het aantal aanvragen dat in het huidige venster over is
x-ratelimit-reset De tijd waarop het venster opnieuw wordt ingesteld, in UTC-epochtijd in seconden

Wanneer u de primaire limiet overschrijdt, retourneert GitHub 403 of 429, waarbij x-ratelimit-remaining is ingesteld op 0. Probeer het pas opnieuw na het tijdstip in x-ratelimit-reset.

Secundaire snelheidslimieten beschermen GitHub tegen pieken, zoals te veel gelijktijdige verzoeken of te snel te veel content aanmaken. Wanneer u er één overschrijdt, retourneert GitHub 403 of 429 met een bericht over een secundaire frequentielimiet. Als het antwoord een retry-after header heeft, wacht u zoveel seconden. Wacht anders, minstens een minuut, en verhoog de wachttijd als het verzoek blijft mislukken.

GitHub kan integraties bannen die verzoeken blijven sturen terwijl ze tegen een snelheidslimiet aanlopen. Zie Frequentielimieten voor de REST API in de documentatie van GitHub voor meer informatie.

De primaire aanvraaglimiet simuleren

Gebruik RateLimitingPlugin om aanvragen te tellen en de snelheidslimietheaders van GitHub te retourneren. Als u wilt testen zonder een uur te wachten, gebruikt u een kleine limiet en een kort venster.

Bestand: 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

Voeg de RetryAfterPlugin toe vóór de RateLimitingPlugin in uw configuratiebestand. Als u deze later toevoegt, verwerkt de RateLimitingPlugin de aanvraag voordat de RetryAfterPlugin deze kan controleren.

Definieer in het bestand met aangepaste respons de respons die GitHub terugstuurt wanneer u de primaire aanvraaglimiet overschrijdt.

Bestand: 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"
  }
}

Start Dev Proxy en voer uw app uit.

devproxy --config-file devproxyrc.json

Dev Proxy stuurt de eerste vijf aanvragen in elke minuut door naar GitHub en stelt de x-ratelimit-* headers voor de antwoorden in. Vanaf de 6e aanvraag retourneert Dev Proxy de rate-limitreactie met x-ratelimit-remaining ingesteld op 0 en x-ratelimit-reset ingesteld op het einde van het venster. Als uw app de API opnieuw aanroept voordat het venster opnieuw wordt ingesteld, rapporteert de RetryAfterPlugin dit en beperkt het verzoek.

Controleer of uw app:

  • Leest x-ratelimit-remaining en vertraagt voordat het 0 bereikt.
  • Stopt met het aanroepen van de API na een rate-limitreactie en wacht totdat x-ratelimit-reset.
  • Vertelt de gebruiker wat er gebeurt, bijvoorbeeld 'GitHub ratelimiet is bereikt, probeert het opnieuw om 14:05', in plaats van stilletjes te falen.

Note

GitHub retourneert 429 of 403 wanneer u een frequentielimiet overschrijdt. Als u wilt testen of uw app ook met 403 overweg kan, wijzigt u statusCode in 403. De RetryAfterPlugin traceert alleen 429 reacties, dus het rapporteert geen vroege retries na een 403.

Tip

Dev Proxy stuurt aanvragen door naar GitHub totdat de gesimuleerde limiet is bereikt. Deze aanvragen tellen ook mee voor uw werkelijke GitHub-ratelimiet.

Secundaire ratelimieten simuleren

Secundaire snelheidslimieten komen in bursts en bevatten een retry-after header. Gebruik de GenericRandomErrorPlugin om ze willekeurig te retourneren.

Bestand: 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
  }
}

Bestand: 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"
          }
        }
      ]
    }
  ]
}

Start Dev Proxy en voer uw app uit. Controleer of uw app wacht op het aantal seconden in de retry-after header voordat uw app de API opnieuw aanroept. Als dat niet zo is, meldt RetryAfterPlugin het.

Als u Octokit gebruikt met de throttling-plug-in, controleert u of uw onRateLimit- en onSecondaryRateLimit-handlers worden uitgevoerd en of ze het resultaat retourneren dat u verwacht.

Volgende stap

Meer informatie over de RateLimitingPlugin.

Zie ook