Gunicorn (獨角獸)是一個高效的Python WSGI Server,一般用它來運行 wsgi application(由咱們本身編寫遵循WSGI application的編寫規範) 或者 wsgi framework(如Django,Paster),地位至關於Java中的Tomcat。html
安裝Gunicorn python
方式一:最簡單的使用 easy_install 安裝或者更新git
1 sudo easy_install -U gunicorn
方式二:下載源碼安裝github
1 git clone git://github.com/benoitc/gunicorn.git 2 cd gunicorn 3 sudo python setup.py install
若是想讓Gunicorn支持異步 workers 的話須要安裝一下三個python包web
1 easy_install -U greenlet 2 easy_install -U eventlet 3 easy_install -U gevent
說明:若是安裝 greenlet 失敗的話,你須要安裝 Python headersdjango
1 sudo apt-get install python-dev
gunicorn還須要庫函數 libevent(1.4.x or 2.0.4) 架構
運行Gunicorn併發
成功安裝 gunicorn 以後有如下三個指令你能夠直接使用,用來啓動 gunicorn 運行 wsgi application或者 wsgi frameworksapp
1 gunicorn 2 gunicorn_django 3 gunicorn_paster
gunicorn框架
Gunicorn server的最基本的命令,直接用來運行最基本的 wsgi application 。
用法:
1 gunicorn [OPTIONS] APP_MODULE
OPTIONS 可選參數 運行gunicorn的配置選項,後面會講到。
APP_MODULE 指定 wsgi application文件,書寫格式 $(MODULE_NAME):$(VARIABLE_NAME)。其中 module_name用來制定將要運行的 wsgi application文件,但是一個完整的點綴名。好比當前目錄 myapp 目錄下有個 Python 包 gunicorn_app, gunicorn_app包下有一個wsgi application文件 test.py 則 module_name能夠直接寫成 gunicorn_app.test。viriable_name表示在 module_name 文件中要調用的對象(是一個WSGI callable, 能夠是一個函數,類詳情參看WSGI規格說明書)名。
按照上面的例子,當前目錄爲 /home/user/myapp, myapp中有一個包 gunicorn_app,test.py代碼以下:
1 def app(environ, start_response): 2 """Simplest possible application object""" 3 data = 'Hello, World!\n' 4 status = '200 OK' 5 response_headers = [ 6 ('Content-type','text/plain'), 7 ('Content-Length', str(len(data))) 8 ] 9 start_response(status, response_headers) 10 return iter([data])
咱們將要運行 test.py文件中的 app(固然名字由你決定,能夠是myapp,demo等等)
1 gunicorn gunicorn_app.test:app
命令中 module_name 爲 gunicorn_app.test ;viriable_name爲 app。固然若是咱們這樣直接運行Gunicorn的話,Gunicorn的全部配置都是默認值,後面會講到如何配置Gunicorn。
gunicorn_django
guniorn_django命令是用來將 Django app部署到 Gunicorn Server上的。
其實也很是簡單,原理和 gunicorn同樣,只是gunicorn_django作了特殊處理,使得更加適合Django
基本用法
1 gunicorn_django [OPTIONS] [SETTINGS_PATH]
OPTIONS 前面已經說過了。
SETTINGS_PATH django app中 settings.py文件所在的目錄,不寫的話默認在當前目錄下查找。好比:
1 gunicorn_django
這種用法適用以 Django 1.4 之前。
對於Django 1.4的版本之後推薦使用 gunicorn 命令(強烈推薦)
1 django_admin.py startproject mysite 2 cd mysite 3 gunicorn mysite.wsgi:application
還有一種方法是使用 Gunicorn內嵌的Djangohttps://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/gunicorn/不推薦。
至於 gunicorn_paster 有興趣的能夠研究 Gunicorn或者Paster官方文檔。
Gunicorn配置
Gunicorn從三個不一樣的地方讀取配置信息。
第一個地方:從framework定義的配置信息中讀取,目前只對 Paster 框架有效。
第二個地方:在命令行中定義,命令行中定義的配置信息將會覆蓋掉框架中定義的相同的參數名的值。
最後:將全部的參數信息,放到一個文件中,只要是在命令行中能夠定義的參數中,在配置文件中均可以定義。(是一個Python源文件,因此你就像在寫Python代碼同樣)
第一個地方不不介紹了,不實用。重點介紹第二種和第三種,其實這兩種方式都是相同的。
顯示說有配置選項:
1 gunicorn -h
使用命令行配置:
在上面的 myapp 例子的基礎上
1 gunicorn --workers=4 --bind=127.0.0.1:8000 myapp.test:app
上面的命令 啓動 4個 workers ,綁定到 127.0.0.1:8000
使用配置文件
配置文件 config.py 源碼
1 import multiprocessing 2 3 bind = "127.0.0.1:8001" 4 workers = multiprocessing.cpu_count() * 2 + 1
使用配置文件啓動Gunicorn
1 gunicorn --config=config.py myapp.test:app
和上面用命令行配置的效果徹底同樣。
固然二者還能夠結合起來用:
1 gunicorn --config=gunicorn_conf.py --worker-class=eventlet myapp.test:app
worker-class默認是sync(同步),咱們配置成了 eventlet(併發的)
Gunicorn的架構
服務模型(Server Model)
Gunicorn是基於 pre-fork 模型的。也就意味着有一箇中心管理進程( master process )用來管理 worker 進程集合。Master從不知道任何關於客戶端的信息。全部的請求和響應處理都是由 worker 進程來處理的。
Master(管理者)
主程序是一個簡單的循環,監聽各類信號以及相應的響應進程。master管理着正在運行的worker集合,經過監聽各類信號好比TTIN, TTOU, and CHLD. TTIN and TTOU響應的增長和減小worker的數目。CHLD信號代表一個子進程已經結束了,在這種狀況下master會自動的重啓失敗的worker。
Worker類型:
Sync Workers
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.
Async Workers
The asynchronous workers available are based on Greenlets (via Eventlet and Gevent). 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.
Tornado Workers
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.
Choosing a Worker Type
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.
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, Slowloris is an example of this type of load.
Some examples of behavior requiring asynchronous workers:
- Applications making long blocking calls (Ie, external web services)
- Serving requests directly to the internet
- Streaming requests and responses
- Long polling
- Web sockets
- Comet
How Many Workers?
DO NOT scale the number of workers to the number of clients you expect to have. 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. 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.
Obviously, your particular hardware and application are going to affect the optimal number of workers. Our recommendation is to start with the above guess and tune using TTIN and TTOU signals while the application is under load.
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。