diff --git a/gunicorn/config.py b/gunicorn/config.py index c41add5c..2094f1fe 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -628,6 +628,23 @@ class MaxRequests(Setting): """ +class MaxRequestsJitter(Setting): + name = "max_requests_jitter" + section = "Worker Processes" + cli = ["--max-requests-jitter"] + meta = "INT" + validator = validate_pos_int + type = int + default = 0 + desc = """\ + The maximum jitter to add to the max-requests setting. + + The jitter causes the restart per worker to be randomized by + randint(0, max_requests_jitter). This is intended to stagger worker + restarts to avoid all workers restarting at the same time. + """ + + class Timeout(Setting): name = "timeout" section = "Worker Processes" diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index 8f75805f..599fb62e 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -7,6 +7,7 @@ from datetime import datetime import os import signal import sys +from random import randint from gunicorn import util @@ -44,7 +45,8 @@ class Worker(object): self.aborted = False self.nr = 0 - self.max_requests = cfg.max_requests or MAXSIZE + jitter = randint(0, cfg.max_requests_jitter) + self.max_requests = cfg.max_requests + jitter or MAXSIZE self.alive = True self.log = log self.tmp = WorkerTmp(cfg)