mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
128 lines
6.5 KiB
HTML
128 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Green Unicorn - Design</title>
|
|
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
|
|
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" />
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div id="header">
|
|
<a href="./">
|
|
<img src="images/logo.png" alt="Gunicorn - Green Unicorn" />
|
|
</a>
|
|
</div>
|
|
<div id="menu">
|
|
<ul id="actions">
|
|
<li><a href="install.html">Install</a></li>
|
|
<li><a href="run.html">Run</a></li>
|
|
<li><a href="configure.html">Configure</a></li>
|
|
<li><a href="deploy.html">Deploy</a></li>
|
|
<li><a href="design.html">Design</a><li>
|
|
<li><a href="faq.html">FAQ</a></li>
|
|
<li><a href="news.html">News</a></li>
|
|
<li><a href="http://github.com/benoitc/gunicorn/">Code</a></li>
|
|
</ul>
|
|
</div>
|
|
<div id="content">
|
|
<div class="document">
|
|
<div class="contents sidebar topic" id="contents">
|
|
<p class="topic-title first">Contents</p>
|
|
<ul class="simple">
|
|
<li><a class="reference internal" href="#server-model" id="id1">Server Model</a><ul>
|
|
<li><a class="reference internal" href="#master" id="id2">Master</a></li>
|
|
<li><a class="reference internal" href="#sync-workers" id="id3">Sync Workers</a></li>
|
|
<li><a class="reference internal" href="#async-workers" id="id4">Async Workers</a></li>
|
|
<li><a class="reference internal" href="#tornado-workers" id="id5">Tornado Workers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#choosing-a-worker-type" id="id6">Choosing a Worker Type</a></li>
|
|
<li><a class="reference internal" href="#how-many-workers" id="id7">How Many Workers?</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="server-model">
|
|
<h2><a class="toc-backref" href="#contents">Server Model</a></h2>
|
|
<p>Gunicorn is based on the pre-fork worker model. This means that there is a
|
|
central master process that manages a set of worker processes. The master
|
|
never knows anything about individual clients. All requests and responses are
|
|
handled completely by worker processes.</p>
|
|
<div class="section" id="master">
|
|
<h3><a class="toc-backref" href="#contents">Master</a></h3>
|
|
<p>The master process is a simple loop that listens for various process signals
|
|
and reacts accordingly. It manages the list of running workers by listening
|
|
for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
|
|
increase or decrease the number of running workers. CHLD indicates that a child
|
|
process has terminated, in this case the master process automatically restarts
|
|
the failed worker.</p>
|
|
</div>
|
|
<div class="section" id="sync-workers">
|
|
<h3><a class="toc-backref" href="#contents">Sync Workers</a></h3>
|
|
<p>The most basic and the default worker type is a synchronous worker class that
|
|
handles a single request at a time. This model is the simplest to reason about
|
|
as any errors will affect at most a single request. Though as we describe below
|
|
only processing a single request at a time requires some assumptions about how
|
|
applications are programmed.</p>
|
|
</div>
|
|
<div class="section" id="async-workers">
|
|
<h3><a class="toc-backref" href="#contents">Async Workers</a></h3>
|
|
<p>The asynchronous workers available are based on <a class="reference external" href="http://bitbucket.org/ambroff/greenlet">Greenlets</a> (via <a class="reference external" href="http://eventlet.net">Eventlet</a> and
|
|
<a class="reference external" href="http://gevent.org">Gevent</a>). Greenlets are an implementation of cooperative multi-threading for
|
|
Python. In general, an application should be able to make use of these worker
|
|
classes with no changes.</p>
|
|
</div>
|
|
<div class="section" id="tornado-workers">
|
|
<h3><a class="toc-backref" href="#contents">Tornado Workers</a></h3>
|
|
<p>There's also a Tornado worker class. It can be used to write applications using
|
|
the Tornado framework. Although the Tornado workers are capable of serving a
|
|
WSGI application, this is not a recommended configuration.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="choosing-a-worker-type">
|
|
<h2><a class="toc-backref" href="#contents">Choosing a Worker Type</a></h2>
|
|
<p>The default synchronous workers assume that your application is resource bound
|
|
in terms of CPU and network bandwidth. Generally this means that your
|
|
application shouldn't do anything that takes an undefined amount of time. For
|
|
instance, a request to the internet meets this criteria. At some point the
|
|
external network will fail in such a way that clients will pile up on your
|
|
servers.</p>
|
|
<p>This resource bound assumption is why we require a buffering proxy in front of a
|
|
default configuration Gunicorn. If you exposed synchronous workers to the
|
|
internet, a DOS attack would be trivial by creating a load that trickles data to
|
|
the servers. For the curious, <a class="reference external" href="http://ha.ckers.org/slowloris/">Slowloris</a> is an example of this type of load.</p>
|
|
<p>Some examples of behavior requiring asynchronous workers:</p>
|
|
<blockquote>
|
|
<ul class="simple">
|
|
<li>Applications making long blocking calls (Ie, external web services)</li>
|
|
<li>Serving requests directly to the internet</li>
|
|
<li>Streaming requests and responses</li>
|
|
<li>Long polling</li>
|
|
<li>Web sockets</li>
|
|
<li>Comet</li>
|
|
</ul>
|
|
</blockquote>
|
|
</div>
|
|
<div class="section" id="how-many-workers">
|
|
<h2><a class="toc-backref" href="#contents">How Many Workers?</a></h2>
|
|
<p>Gunicorn relies on the operating system to provide all of the load balancing
|
|
when handling requests. Generally we recommend <tt class="docutils literal">(2 x $num_cores) + 1</tt> as the
|
|
number of workers to start off with. While not overly scientific, the formula
|
|
is based on the assumption that for a given core, one worker will be reading
|
|
or writing from the socket while the other worker is processing a request.</p>
|
|
<p>Obviously, your particular hardware and application are going to affect what
|
|
the optimal number of workers is. Our recommendation is to start with the above
|
|
guess and tune using TTIN and TTOU signals while the application is under load.</p>
|
|
<p>Always remember, there is such a thing as too many workers. After a point your
|
|
worker processes will start thrashing system resources decreasing the throughput
|
|
of the entire system.</p>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div id="footer">
|
|
<p>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a>.</p>
|
|
<p>Hosted on <a href="http://github.com/">Github</a></p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |