Gunicorn を使用した Django アプリへの 100 件の同時リクエストにより、「54: ピアによる接続のリセット」と 502 が発生します。

Gunicorn を使用した Django アプリへの 100 件の同時リクエストにより、「54: ピアによる接続のリセット」と 502 が発生します。

私は API エンドポイントとして機能する Django アプリをホストしています。残念ながら、API を使用するアプリは、ページの読み込み時に多数の同時リクエスト (80 ~ 90 リクエストの範囲) を実行します。

Nginx は gunicorn の前でリバース プロキシとして実行されており、次の問題を報告します。 kevent() reported that connect() failed (54: Connection reset by peer) while connecting to upstream

それが、gunicorn のスケーリングにつながりました。-k geventと を増やしてみました--worker-connectionsが、あまり効果はありませんでした。 と--threadssync-workers でもほぼ同じような効果がありました。

Listen queue overflow: 16 already in queue awaiting acceptance (55 occurrences)で が数回出現することに気づいたので、 4096 までdmesg増やしてみましたが、やはり成功しませんでした。kern.ipc.somaxconn

gunicorn のドキュメントに従って、heyプロキシが適切に動作しているかどうかを確認し、エンドポイントの負荷テストを実行するために使用します。 hey -c 100 -n 200 -H "Authorization: token ${token}" 'https://example.com/api/'

次のような結果が返されます (場合によっては少し良くなり、場合によっては少し悪くなります)。

Status code distribution:
  [200] 126 responses
  [502] 74 responses

関連する nginx-config:

worker_processes  auto;

events {
    worker_connections  1024;
    accept_mutex on;
    use kqueue;
}

upstream backend-api {
  server 127.0.0.1:8000 fail_timeout=0;
}

server {
    listen 443 ssl http2 accept_filter=httpready;
    server_name example.com;

    ssl_certificate /usr/local/etc/nginx/sites/example.com.crt;
    ssl_certificate_key /usr/local/etc/nginx/sites/example.com.key;

    location = /favicon.ico { access_log off; log_not_found off; }
    root /usr/local/www/example.com/web;
    index index.html ;

    keepalive_timeout 5;

    location ~  ^/(static|assets|index.html|$) {
        root /usr/local/www/example.com/web;
    }

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Forwarded-Host $http_host;
      proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_intercept_errors on;
      proxy_pass http://backend-api;
    }
}

gunicorn を実行するには: gunicorn --workers=9 --bind 0.0.0.0:8000 --forwarded-allow-ips='*' -k gevent --worker-connections=1000 api.wsgi'

これに対する解決策が見つからないようです。何を試しても、ページ読み込み時に 502 が「少なく」なるだけで、確実にゼロになることはありません。何が足りないのでしょうか?

Gunicorn は問題を報告しません。リクエストがそこまで到達することは決してないようです。

関連情報