Watched the below post on architecture over at Meebo
Got me thinking about:
Pre Forking with aynchronous servers
In general I was interested in the issue of running asynchronous servers on multiple processors/cores.
Seems that this can be done in multiple servers:
Ruby Unicorn
Python Gunicorn
Facebook Tornado Python server
Meebo talk on asynchronous architecture
Apache CGI process per request - memory efficiency sucks!
Apache mod_wsgi
Twisted
Gevent + Gunicorn
http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-using-coroutines-to-create-efficient-high-concurrency-web-applications-4900984
-----
Gevent + Gunicorn
For SSL support, both Gunicorn and Tornado recommend you run them behind a reverse proxy such as nginx.
Gunicorn - Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model ported from Ruby's Unicorn project.
Greins - Greins is a Gunicorn application which makes it easy to configure and manage any number of WSGI apps in one server daemon.
https://github.com/meebo/greins
https://github.com/srlindsay/gevent-profiler
http://stackoverflow.com/questions/13852752/is-gevent-gunicorn-scalable-and-stable-for-production-use
------
Facebook Tornado
Ways to run Tornado
1. listen: simple single-process:
2. bind/start: simple multi-process:
3. add_sockets: advanced multi-process:
http://www.tornadoweb.org/documentation/httpserver.html
Background
The "pre-forking" phrase is used to mean a couple of different things, so it is worth clarifying what it means for Tornado. Essentially, we bind a single server socket to a port, and we fork() one process per CPU. Each of those CPUs calls accept() on the shared server socket, and the Linux kernel gives new requests to one of the child processes on a first-come-first-serve basis. Each of the child processes has their own epoll-based IO loop, and a single request is handled entirely within one of the child processes. There is no shared memory or shared state between the forked child processes, only a shared port.
-----
In the classic setup you have nginx sending requests to a pool of mongrels using a smart balancer or a simple round robin. Eventually you want better visibility and reliability out of your load balancing situation, so you throw haproxy into the mix:
Http Proxy Load Balancer Cluster of web servers
Nginx -> Haproxy -> (Mongrel or Unicorn or …)
https://github.com/blog/517-unicorn
-----
Ruby's unicorn
Unicorn is a traditional UNIX prefork web server. No threads are used at all, this makes applications easier to debug and fix. When your application goes awry, a BOFH can just “kill -9” the runaway worker process without worrying about tearing all clients down, just one. Only UNIX-like systems supporting fork() and file descriptor inheritance are supported.
http://unicorn.bogomips.org/DESIGN.html
While reading up on these topics I found out about WSGI which is the equivalent of Ruby's Rack as far as I can tell.
http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
Quick note on how nginx fits in.
Varnish is an HTTP accelerator designed for content-heavy dynamic web sites. In contrast to other HTTP accelerators, such as Squid, which began life as a client-side cache, or Apache and nginx, which are BOLDprimarily origin serversBOLD, Varnish was designed as an HTTP accelerator. Varnish is focused exclusively on HTTP, unlike other proxy servers that often support FTP, SMTP and other network protocols.
No comments:
Post a Comment