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ぐらいにしておくと、いい感じのバラけ具合になるでしょう。