I'm trying to run a simple flask app through gunicorn, but having my workers timeout no matter what I do. Whether there's activity against the app or not, workers will always timeout after whatever I set the timeout
value to. What's causing them to timeout? Requests go through successfully when I make them, but workers still timeout. Here's what I'm running:
gunicorn test_app.py -b 127.0.0.1:8000 --log-level=debug --log-file /tmp/log
* Running on http://127.0.0.1:5000/
127.0.0.1 - - [28/Aug/2014 11:23:50] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [28/Aug/2014 11:23:53] "GET / HTTP/1.1" 200 -
* Running on http://127.0.0.1:5000/
* Running on http://127.0.0.1:5000/
And here's what I'm seeing in /tmp/log:
[2014-08-28 11:23:32 -0700] [36868] [INFO] Listening at: http://127.0.0.1:8000 (36868)
[2014-08-28 11:23:32 -0700] [36868] [INFO] Using worker: sync
[2014-08-28 11:23:32 -0700] [36871] [INFO] Booting worker with pid: 36871
[2014-08-28 11:23:32 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:02 -0700] [36868] [CRITICAL] WORKER TIMEOUT (pid:36871)
[2014-08-28 11:24:02 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:03 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:03 -0700] [36872] [INFO] Booting worker with pid: 36872
[2014-08-28 11:24:03 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:03 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:33 -0700] [36868] [CRITICAL] WORKER TIMEOUT (pid:36872)
[2014-08-28 11:24:33 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:33 -0700] [36872] [INFO] Worker exiting (pid: 36872)
[2014-08-28 11:24:33 -0700] [36873] [INFO] Booting worker with pid: 36873
[2014-08-28 11:24:33 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:24:33 -0700] [36868] [DEBUG] 1 workers
[2014-08-28 11:25:03 -0700] [36868] [CRITICAL] WORKER TIMEOUT (pid:36873)
As you can see, my worker times out every 30 seconds, even though there's nothing wrong with it. What gives?
Worker timeouts By default, Gunicorn gracefully restarts a worker if hasn't completed any work within the last 30 seconds. If you expect your application to respond quickly to constant incoming flow of requests, try experimenting with a lower timeout configuration. $ gunicorn hello:app --timeout 10.
Each of the workers is a UNIX process that loads the Python application. There is no shared memory between the workers. The suggested number of workers is (2*CPU)+1 . For a dual-core (2 CPU) machine, 5 is the suggested workers value.
After 30 seconds (configurable with timeout ) of request processing, gunicorn master process sends SIGTERM to the worker process, to initiate a graceful restart. If worker does not shutdown during another 30 seconds (configurable with graceful_timeout ), master process sends SIGKILL .03-Apr-2017.
Gunicorn should only need 4-12 worker processes to handle hundreds or thousands of requests per second. Gunicorn relies on the operating system to provide all of the load balancing when handling requests.
For anyone having this issue in the future, the main problem was me doing:
app.run()
and not
if __name__ == '__main__':
app.run()
with the former, the workers would wind up being run through flask instead of gunicorn, and the whole thing would become confused. Just switching to the latter fixed my issue.
Usually worker timeout will happen if the request take more time. Try add new parameter called --timeout <some value>
it should work.
ex: gunicorn test_app.py -b 127.0.0.1:8000 --log-level=debug --log-file /tmp/log -t 900
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With