Je reçois le message « 429 Trop de requêtes » pour les requêtes API vers mon instance auto-hébergée, même avec :
DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE augmenté à 600
Je l’ai défini dans la section env de app.yml, puis j’ai exécuté ./launcher rebuild et j’ai confirmé que la variable était définie dans le conteneur reconstruit.
C’est bien plus que le nombre de requêtes par minute que je tente.
une clé API administrateur sans restriction
Il semble que cela ait déjà été discuté sans réponse claire quant à la raison pour laquelle la modification de DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE ne semble pas fonctionner :
Je me penche à nouveau sur ce problème car nous avons lancé une intégration Discourse et nous voulons nous assurer de ne rencontrer aucun problème lié aux limites de débit.
Je l’ai testé avec une nouvelle clé pour m’assurer qu’elle n’est limitée d’aucune façon. Pour être clair, que voulez-vous dire exactement par clé API d’administrateur ?
Il est indiqué : « La clé API n’a aucune restriction et tous les points d’accès sont accessibles ».
Je teste cela en effectuant des requêtes API depuis un shell Python local, donc elles proviennent de la même adresse IP. Nous avons également rencontré les limites de débit lors de l’exécution d’un script sur notre serveur. Dans ce cas, toutes les requêtes provenaient de la même adresse IP.
J’ai confirmé que la limite de débit est atteinte avec le code suivant :
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
# Obtenez simplement une tranche de 15 des sujets dans topic_ids pour le test.
topics = asyncio.run(get_topic_post_streams(topic_ids[:15]))
Notez que le paramètre max_per_second est commenté, ce qui n’impose aucune limite au nombre de requêtes.
Cela se termine en 2,05 s et 2 des 15 requêtes retournent 429.
Lorsque je l’exécute avec max_per_second=1, tout se termine avec succès.
Faites-moi savoir si je peux fournir plus de détails. Merci !
Il me semble que je ne devrais pas recevoir ces 429, quels que soient les paramètres mentionnés dans ce post. Dans l’exemple que j’ai fourni, j’ai envoyé 15 requêtes, ce qui est inférieur à toutes les limites par défaut de l’API. Je l’ai fait en utilisant une clé d’API et un nom d’utilisateur d’administrateur.
L’exemple ne dépasse pas les valeurs par défaut par adresse IP :
Il ne dépasse même pas les limites non administratives :
Changer DISCOURSE_MAX_REQS_PER_IP_MODE en warn ou none n’a pas aidé.
Est-ce que je manque quelque chose ?
Au fait, j’ai modifié les paramètres en éditant app.yml et en exécutant ./launcher destroy app && ./launcher start app.
Je peux voir dans /var/log/nginx/access.log que l’adresse IP est correcte, donc je ne pense pas que Discourse considère que toutes les requêtes proviennent de la même IP.
Je peux également voir les adresses IP des utilisateurs dans l’administration.
EDIT : Je viens de vérifier le contenu de la réponse d’une des requêtes échouées et j’ai remarqué qu’elle mentionnait nginx :
<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
Je vais enquêter davantage sur les sujets qui mentionnent nginx.
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;
}
}
Mes questions restantes sont maintenant :
Dois-je modifier les deux sections pour qu’elles correspondent à mes paramètres Discourse ? Ou seulement les valeurs pour location @discourse ?
Quelle est la bonne façon de modifier ces valeurs et de conserver les modifications lors des reconstructions ?
Je suppose que je peux modifier la configuration nginx directement dans le conteneur, puis arrêter/démarrer le conteneur. Mais il semble que ces valeurs proviennent à l’origine de templates/web.ratelimited.template.yml et peuvent être écrasées lors d’une reconstruction ?
Ouf, là on sort de ma zone de confort, j’ai bien peur.
Si vous êtes limité par le débit par nginx, alors oui, modifier ces paramètres et les rendre moins restrictifs a du sens. Je ne suis pas sûr que Nginx puisse mettre des adresses IP sur liste blanche ?
Oui, vous devriez faire quelques remplacements avec des pups lors de la construction pour rendre cela persistant, voir par exemple web.ssl.template.yml pour savoir comment aborder cela.
Ou vous pourriez oublier cela et faire en sorte que votre script client API s’exécute plus lentement en insérant quelques sleep à des endroits stratégiques. ← approche recommandée