Ich erhalte die Meldung „429 Too Many Requests“ für API-Anfragen an meine selbst gehostete Instanz, selbst mit:
DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE erhöht auf 600
Ich habe dies im env-Abschnitt von app.yml festgelegt und dann ./launcher rebuild ausgeführt und bestätigt, dass die Variable im neu erstellten Container gesetzt wurde.
Dies ist weit mehr als die Anzahl der Anfragen pro Minute, die ich versuche.
Ein uneingeschränkter Admin-API-Schlüssel.
Es scheint, dass dies bereits ohne klare Antwort diskutiert wurde, warum die Änderung von DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE nicht zu funktionieren scheint:
Ich schaue mir das jetzt noch einmal an, da wir eine Discourse-Integration gestartet haben und sicherstellen wollen, dass wir keine Probleme mit Ratenbegrenzungen bekommen.
Ich habe es mit einem neuen Schlüssel getestet, um sicherzugehen, dass er in keiner Weise eingeschränkt ist. Um genau zu sein, was meinen Sie genau mit einem Admin-API-Schlüssel?
Ich habe einen Schlüssel mit den folgenden Einstellungen erstellt:
Dort steht: „API-Schlüssel hat keine Einschränkung und alle Endpunkte sind zugänglich.“
Ich teste dies, indem ich API-Anfragen von einer lokalen Python-Shell aus sende, sodass sie von derselben IP-Adresse kommen. Wir sind auch auf Ratenbegrenzungen gestoßen, als wir ein Skript auf unserem Server ausgeführt haben. In diesem Fall kamen alle Anfragen von derselben IP-Adresse.
Ich habe bestätigt, dass die Ratenbegrenzung mit dem folgenden Code erreicht wird:
async def get_topic_post_stream(topic_id):
url = f"{DISCOURSE_URL}/t/{topic_id}"
async with httpx.AsyncClient(headers=HEADERS) as client:
topic = await client.get(url)
return topic.status_code
async def get_topic_post_streams(topic_ids):
tasks = [functools.partial(get_topic_post_stream, topic_id) for topic_id in topic_ids]
topics = await aiometer.run_all(
tasks,
# max_per_second=1,
)
return topics
# Holen Sie sich nur einen Ausschnitt von 15 der Themen in topic_ids zum Testen.
topics = asyncio.run(get_topic_post_streams(topic_ids[:15]))
Beachten Sie, dass der Parameter max_per_second auskommentiert ist, was zu keinen Einschränkungen bei der Anzahl der Anfragen führt.
Dies ist in 2,05 Sekunden abgeschlossen und 2 der 15 Anfragen geben 429 zurück.
Wenn ich es mit max_per_second=1 ausführe, ist alles erfolgreich abgeschlossen.
Lassen Sie mich wissen, wenn ich weitere Details angeben kann. Danke!
Wenn ich raten müsste, ist dies höchstwahrscheinlich das Problem. Sie werden nicht auf API-Basis, sondern auf IP-Basis einer Ratenbegrenzung unterzogen.
Meiner Meinung nach sollte ich diese 429er unabhängig von den in diesem Beitrag genannten Einstellungen nicht erhalten. In dem von mir bereitgestellten Beispiel habe ich 15 Anfragen gesendet, was unter allen Standard-API-Grenzwerten liegt. Ich habe dies mit einem Admin-API-Schlüssel und Benutzernamen getan.
Das Beispiel überschreitet nicht die folgenden Standardwerte pro IP:
Es überschreitet nicht einmal die Limits für Nicht-Admins:
Das Ändern von DISCOURSE_MAX_REQS_PER_IP_MODE auf warn oder none hat nicht geholfen.
Fehlt mir etwas?
Übrigens habe ich die Einstellungen geändert, indem ich app.yml bearbeitet und ./launcher destroy app && ./launcher start app ausgeführt habe.
Ich kann in /var/log/nginx/access.log sehen, dass die IP-Adresse korrekt ist, daher glaube ich nicht, dass Discourse alle Anfragen von derselben IP erhält.
Ich kann auch die IP-Adressen der Benutzer im Adminbereich sehen.
Dies sind die Einstellungen, die ich geändert habe:
EDIT: Ich habe gerade den Antwortinhalt einer der fehlgeschlagenen Anfragen überprüft und festgestellt, dass nginx erwähnt wurde:
<html>\r\n<head><title>429 Too Many Requests</title></head>\r\n<body>\r\n<center><h1>429 Too Many Requests</h1></center>\r\n<hr>\n<center>nginx</center>\r\n</body>\r\n</html>\r\n
Ich werde weitere Nachforschungen zu den Themen anstellen, die nginx erwähnen.
location @discourse {
add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for this domain
limit_conn connperip 20;
limit_req zone=flood burst=12 nodelay;
limit_req zone=bot burst=100 nodelay;
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
}
}
Meine verbleibenden Fragen sind nun:
Soll ich beide Abschnitte bearbeiten, um sie an meine Discourse-Einstellungen anzupassen? Oder nur die Werte für location @discourse?
Wie kann ich diese Werte korrekt ändern und die Änderungen über Rebuilds hinweg beibehalten?
Ich nehme an, ich kann die nginx-Konfiguration direkt im Container bearbeiten und dann den Container stoppen/starten. Aber es sieht so aus, als ob diese Werte ursprünglich aus templates/web.ratelimited.template.yml stammen und bei einem Rebuild überschrieben werden könnten?
Autsch, da verlassen wir jetzt wohl meinen Komfortbereich, fürchte ich.
Wenn Sie von Nginx rate-limited werden, dann macht es Sinn, an diesen Einstellungen herumzuspielen und sie weniger restriktiv zu machen. Ich bin mir nicht sicher, ob Nginx IP-Adressen auf eine Whitelist setzen kann?
Ja, Sie sollten einige Ersetzungen mit Pups während des Builds vornehmen, um dies persistent zu machen. Sehen Sie sich zum Beispiel web.ssl.template.yml an, wie Sie dies angehen können.
Oder Sie könnten das vergessen und Ihr API-Client-Skript langsamer laufen lassen, indem Sie an strategischen Stellen einige Sleeps einfügen. ← empfohlener Ansatz
[quote=„Richard – Communiteq, Beitrag: 10, Thema: 274206, Benutzername: RGJ“]Man könnte das vergessen und sein API-Client-Skript langsamer laufen lassen, indem man an strategischen Stellen einige Pausen einlegt.
[/quote]
Wie in einem rescue, wenn es Ratenbegrenzungen erhält. Das ist es, was ich normalerweise tue.