Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use eventlet library for async gunicorn workers

One of my django projects is deployed using ansible (gunicorn & nginx). Below is gunicorn configuration :

bind = '127.0.0.1:8001'
backlog = 2048

workers = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 300
keepalive = 2

spew = False

daemon = False
pidfile = None
umask = 0
user = None
group = None
tmp_upload_dir = None

loglevel = 'info'
errorlog = '/var/log/error.log'
accesslog = '/var/log/access.log'

proc_name = None

def pre_fork(server, worker):
    pass

def pre_exec(server):
    server.log.info("Forked child, re-executing.")

def when_ready(server):
    server.log.info("Server is ready. Spawning workers")

def worker_int(worker):
    worker.log.info("worker received INT or QUIT signal")


    ## get traceback info
    import threading, sys, traceback
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
    code = []
    for threadId, stack in sys._current_frames().items():
        code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""),
            threadId))
        for filename, lineno, name, line in traceback.extract_stack(stack):
            code.append('File: "%s", line %d, in %s' % (filename,
                lineno, name))
            if line:
                code.append("  %s" % (line.strip()))
    worker.log.debug("\n".join(code))

def worker_abort(worker):
    worker.log.info("worker received SIGABRT signal")

The worker processes are running synchronously. I want them to run concurrently as I have a lot of requests per minute on this server. On research I got to find that I can use python libraries like eventlet which uses greenthreads for concurrency.For this I need to change the worker_class to eventlet as :

worker_class = eventlet

But now I am clueless. I don't get how to implement the asynchronous green threads for this project. May be this is a stupid question but I really need some help.

Thanks in advance.

like image 823
the_unknown_spirit Avatar asked Aug 10 '16 14:08

the_unknown_spirit


People also ask

What is Gunicorn eventlet?

Gunicorn provides a much more configurable and production-tested server. eventlet allows writing asynchronous, coroutine-based code that looks like standard synchronous Python. It uses greenlet to enable task switching without writing async/await or using asyncio . gevent is another library that does the same thing.

Does Gunicorn support async?

The default sync worker is appropriate for many use cases. If you need asynchronous support, Gunicorn provides workers using either gevent or eventlet. This is not the same as Python's async/await , or the ASGI server spec. You must actually use gevent/eventlet in your own code to see any benefit to using the workers.

How many workers can Gunicorn handle?

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.

How many Gunicorn workers should I run?

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. Generally we recommend (2 x $num_cores) + 1 as the number of workers to start off with.


1 Answers

You've already done everything required. worker_class = eventlet or gunicorn -k eventlet is enough to run HTTP request handlers concurrently. And then you can serve many concurrent requests with sleep or IO in their handlers.

like image 145
temoto Avatar answered Sep 24 '22 12:09

temoto