[gevent] gevent's WSGI server -- proxy, multicore, spawn

1,107 views
Skip to first unread message

Andy

unread,
Apr 18, 2010, 8:45:41 AM4/18/10
to gevent: coroutine-based Python network library
A few questions:

- is it a good idea to run a reverse proxy like Nginx in front of
gevent's WSGI server? The normal reason to have a reverse proxy is to
reduce concurrency on the app server and to buffer slow client
connections -- do those reasons still apply to gevent?

- In the example http://bitbucket.org/denis/gevent/src/tip/examples/webchat/run.py
presumably only 1 python process & 1 python thread are created. In
that case it wouldn't be able to take advantage of multiple CPU cores.
What is the recommended way to make gevent wsgi server run on
multicore CPU? In gevent.wsgi.WSGIServer in base_env both
'wsgi.multithread' & 'wsgi.multiprocess' are set to False. If I change
that to True would that make the wsgi server multiprocess/
multthreaded?
Or should I just put a load balancer in front of multiple WSGIServer
processes each running on its own core? In that case how do I start up
multiple WSGIServer processes?

- When does it make sense to use "spawn=None" when starting a
WSGIServer, and when does it not?

Thanks


--
Subscription settings: http://groups.google.com/group/gevent/subscribe?hl=en

Denis Bilenko

unread,
Apr 19, 2010, 5:12:17 AM4/19/10
to gev...@googlegroups.com
On Sun, Apr 18, 2010 at 7:45 PM, Andy <selfor...@gmail.com> wrote:
> A few questions:
>
> - is it a good idea to run a reverse proxy like Nginx in front of
> gevent's WSGI server? The normal reason to have a reverse proxy is to
> reduce concurrency on the app server and to buffer slow client
> connections -- do those reasons still apply to gevent?

Probably not as much as to threading-based or forking server but I
think it will still reduce load
on the application server.
There are other reasons to run your app behind nginx, such as better logging,
better configuration, better security, ability to serve an error
message while app is down,
and not hit python app to serve a static file.

> - In the example http://bitbucket.org/denis/gevent/src/tip/examples/webchat/run.py
> presumably only 1 python process & 1 python thread are created. In
> that case it wouldn't be able to take advantage of multiple CPU cores.
> What is the recommended way to make gevent wsgi server run on
> multicore CPU? In gevent.wsgi.WSGIServer in base_env both
> 'wsgi.multithread' & 'wsgi.multiprocess' are set to False. If I change
> that to True would that make the wsgi server multiprocess/
> multthreaded?

Just setting those values in the dictionary won't change the server's behavior.
It still will be one process and one thread.

> Or should I just put a load balancer in front of multiple WSGIServer
> processes each running on its own core?

That would work.

> In that case how do I start up multiple WSGIServer processes?

fork() and start a bunch of WSGIServers in the child processes.

You might find gunicorn interesting: http://gunicorn.org/
It can use gevent and supports forking multiple workers, reloading on
signals, etc.

>
> - When does it make sense to use "spawn=None" when starting a WSGIServer, and when does it not?

If your requests are short-lived and don't use blocking gevent API.
Most of gevent API is blocking.
The nonblocking functions are:
- everything that has 'block' argument can be made non-blocking by
passing block=False
- everything from gevent.core module
- a number of functions that don't need to wait for anything:
- spawn() function
- start() function on Greenlet and various servers
- set() and clear() on Event class
- put_nowait() and get_nowait() on Queue class
This list is not extensive. To check that a function is non-blocking
check if it switches to the Hub in the code.
Or make an experiment: when you call a blocking function from the Hub
greenlet, you'll get an AssertionError
saying "cannot switch from mainloop to mainloop" or something like that.

If unsure, don't bother with spawn=None.

Andy

unread,
Apr 19, 2010, 11:14:19 AM4/19/10
to gevent: coroutine-based Python network library

> fork() and start a bunch of WSGIServers in the child processes.

Did you mean using os.fork() or gevent.fork()?



> You might find gunicorn interesting:http://gunicorn.org/
> It can use gevent and supports forking multiple workers, reloading on
> signals, etc.

Thanks. I didn't know gunicorn uses gevent.

But if gunicorn uses gevent, how come its performance is so much worse
than gevent in this benchmark: http://nichol.as/benchmark-of-python-web-servers
?

Matt Goodall

unread,
Apr 19, 2010, 11:33:20 AM4/19/10
to gev...@googlegroups.com
On 19 April 2010 16:14, Andy <selfor...@gmail.com> wrote:
>
>> fork() and start a bunch of WSGIServers in the child processes.
>
> Did you mean using os.fork() or gevent.fork()?
>
>
>
>> You might find gunicorn interesting:http://gunicorn.org/
>> It can use gevent and supports forking multiple workers, reloading on
>> signals, etc.
>
> Thanks. I didn't know gunicorn uses gevent.
>
> But if gunicorn uses gevent, how come its performance is so much worse
> than gevent in this benchmark: http://nichol.as/benchmark-of-python-web-servers
> ?

gunicorn's gevent support is optional, and not the detault. Also, I
think the gevent support was in a separate package called grainbows at
the time of Nicholas Piël's blog post.

- Matt

lasizoillo

unread,
Apr 19, 2010, 11:33:36 AM4/19/10
to gev...@googlegroups.com
2010/4/19 Andy <selfor...@gmail.com>:
>
> But if gunicorn uses gevent, how come its performance is so much worse
> than gevent in this benchmark: http://nichol.as/benchmark-of-python-web-servers
> ?

See changes in gunicorn:
http://gunicorn.org/news.html

Gunicorn uses gevent since version 0.7.0 (2010-03-26). The bechmark
uses gunicorn version 0.6.4.

Regards,

Javi
Reply all
Reply to author
Forward
0 new messages