max_requestsとは何か?
gunicornのmax_requestsパラメータを指定すると、各ワーカープロセスが max_requests
回数分リクエストを捌くとプロセスを自動再起動してくれるようになります。
これによってメモリリークを回避し、サーバーのリソース逼迫を防ぐことができます。
max_requestsだけだとどんな問題があるか?
gunicornでは各ワーカープロセスにほぼ均等にリクエストが割り振られるため、全ワーカープロセスが一斉にmax_requests
に達して再起動してしまうケースが発生します。
そうなるとリクエストを捌けるワーカーがいない状態が一瞬できるので、ユーザー側から見ると「あれっ、このサイト突然激重になった?」ということがありえます。
バージョン19.2からの新機能max_requests_jitter
そこで、バージョン19.2からmax_requests_jitterパラメータが追加されました。
Worker
クラスのコードを読むと、__init__
の中でmax_requests
は以下のように設定されています。1
jitter = randint(0, cfg.max_requests_jitter)
self.max_requests = cfg.max_requests + jitter or MAXSIZE
つまり、max_requests_jitter
に0を超える整数を設定すると、各ワーカープロセスのmax_requests
に0からmax_requests_jitter
までのランダムな値が加算されます。これで各ワーカープロセスのmax_requests
が違う値になり、再起動のタイミングがバラけて前述の問題を回避できます。
この機能を提案したのは元Redditのエンジニアalienthさんです。元々Redditで採用していたコードらしいです。
https://github.com/benoitc/gunicorn/pull/862
alienthさんのコメントによると、「Right now we're using a max_requests of 500, and a max_requests_jitter of 200 so that restarts are highly randomized.」とのことなので、max_requests = 500
max_requests_jitter = 200
ぐらいにしておくと、いい感じのバラけ具合になるでしょう。