WSGI是爲python語言定義的通用網關接口,它承擔python web框架(django、flask、web.py等)和web服務器(nginx、apache、lighttpd等)之間的中間層。 html
瀏覽器 chrome、firefox、ie等 | web服務器 nginx、apache等 | 網關接口 CGI、FastCGI、WSGI等 | Python(程序、Web框架) Django、Flask、Tornado等
python中自帶的wsgiref就是一種wsgi接口的標準實現,可是,因爲100%使用python實現等緣由,致使wsgiref實在過於緩慢,只能用於測試和學習。生產環境中咱們須要使用性能更高的服務器,目前經常使用的wsgi服務器有:uWSGI、Gunicorn、twisted.web。 python
uWSGI是用C語言寫的高性能WSGI服務器,安裝uWSGI前咱們須要安裝Python和C編譯器(GCC)。推薦使用python包管理器pip安裝uWSGI。 linux
#安裝最新穩定版 pip install uWSGI #也能夠安裝長期支持版(LTS版本) #pip install http://projects.unbit.it/downloads/uwsgi-lts.tar.gz
在ubuntu下可使用apt-get來安裝 nginx
apt-get install uwsgi
在fedora、redhat、centos下使用yum安裝 git
yum groupinstall "Development Tools" yum install python
編譯安裝,從github下載uwsgi代碼,cd到目錄下 github
python uwsgiconfig.py --build
在終端中輸入如下命令查看uwsgi的版本號,若是輸出正常,說明uswgi已安裝成功 web
$ uwsgi --version 2.0.11.1
咱們能夠編寫一個簡單的wsgi應用來測試uwsgi是否被安裝成功,首先建立一個test.py文件: chrome
# test.py def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"] # python3 #return ["Hello World"] # python2
運行uwsgi: apache
uwsgi --http :8000 --wsgi-file test.py
參數中,http :8000表示使用http協議,端口號爲8000,wigi-file則表示要運行的wsgi應用程序文件。uwsgi運行後打開瀏覽器,訪問http://127.0.0.1:8000/ ,或者是相應服務器地址的8000端口,就能夠看到hello world 頁面了。 django
上面的例子中,咱們用瀏覽器直接訪問了uwsgi運行的python程序(只有一個入口函數的wsgi測試應用test.py),其訪問結構以下所示。
瀏覽器 <-> uWSGI <-> Python
上述方式運行uWSGI服務的過程當中,可使用CTRL+C便可中止服務,在後續的章節中會講到自動管理和部署。
nginx和django的安裝不是本文的重點,故在此略去,只討論配置部分。在這裏,咱們要實現的效果以下:
瀏覽器 <-> nginx <-> uWSGI <-> Django(python)
uWSGI使用的協議不徹底是標準的WSGI協議,咱們須要從Github下載uwsgi_paraments配置文件,並將該文件拷貝到項目路徑中(例如:/user/home/pengquanxin/projects/mysite1/)。
接下來,要配置nginx服務器和uWSGI互通,可使用unix套接字方式和TCP端口方式。在nginx配置文件夾(/etc/naginx/site-enabled 或 /usr/local/etc/nginx/sites-enabled)中新建網站的配置文件mystie_nginx.conf,輸入如下內容:
# mysite_nginx.conf # nginx須要鏈接的上游 upstream django { server unix:///path/to/your/mysite/mysite.sock; # 使用unix套接字 #server 127.0.0.1:8001; # 使用TCP端口請註釋上一行,並取消本行註釋,這裏的端口指的是跑uwsgi的端口 } # nginx服務器配置 server { # 監聽端口 listen 80; # 域名 server_name .example.com; # 編碼 charset utf-8; # 最大上傳大小 client_max_body_size 75M; # Django 的media路徑 location /media { alias /path/to/your/mysite/media; } # 靜態文件路徑 location /static { alias /path/to/your/mysite/static; } # 將動態請求轉發到uwsgi跑的django程序 location / { uwsgi_pass django; include /path/to/your/mysite/uwsgi_params; # 從github上下載的uwsgi_params 文件路徑 } }
你也能夠把這個配置文件放在項目路徑中,而後創建一個連接到nginx配置文件夾:
sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
在部署服務器以前,須要先將Django的靜態文件部署到靜態文件夾中,首先,編輯django網站的settings.py文件
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
而後,運行如下命令
python manage.py collectstatic
在啓動nginx以前,咱們須要先啓動uWSGI,進入項目目錄而後輸入如下命令,在這裏咱們使用unix套接字方式:
#注:django1.6 前的版本須要手動添加wsgi.py uwsgi --socket mysite.sock
若是nginx和uwsgi跑在同一臺服務器上,使用unix套接字就能夠了,unix套接字方式性能要高不少,但不能跨機器訪問。當nginx和uWSGI不在一臺服務器上時,就須要使用TCP端口方式(別忘了更改nginx配置文件,取消相應註釋):
uwsgi --socket :8001 --module mysite.wsgi --chmod-socket=664
接下來,啓動nginx服務器,就能夠訪問django站點了。
到這裏,咱們已經把nginx+uWSGI+Django跑起來了,但uWSGI的參數比較多的時候,每次都要輸入很是麻煩,這時,咱們能夠在django項目目錄下創建一個mysite.uwsgi.ini
[uwsgi] # 項目根目錄路徑(full path) chdir = /path/to/your/project # Django的 wsgi 文件 module = mysite.wsgi # virtualenv目錄 (full path) home = /path/to/virtualenv master = true # 最大工做進程數(CPU密集型建議設爲CPU核心數,IO密集型建議設爲CPU核心數的兩倍) processes = 16 # unix套接字文件路徑 socket = /path/to/your/project/mysite.sock # socket文件權限 # chmod-socket = 664 # 退出時清空環境 vacuum = true
而後,直接根據配置文件運行uwsgi便可:
uwsgi --ini mysite.uwsgi.ini
uWSGI的Epreror模式能夠用來管理機器上部署的uwsgi服務,在這種模式下,會有一個特殊的進程(皇帝)對其它部署的服務(諸侯)進行監視。咱們將全部配置文件(ini或xml文件,如上一節中的mysite.uwsgi.ini)統一放到一個文件夾(如:/etc/uwsgi/vassals)中,而後啓動Emperor模式:
uwsgi --emperor /etc/uwsgi/vassals
這樣,就會自動讀取文件夾中的配置文件,並自動監控這些uwsgi服務: - 檢測文件夾中有新的配置文件時,會啓動新的uwsgi服務實例 - 檢測到一個配置文件發生改變,會自動重啓該服務 - 檢測到一個配置文件被移除,則自動中止該服務 - 若是一個服務死了(諸侯),皇帝進程會重啓該服務 - 若是監控進程(皇帝)死了,全部服務(諸侯)都會中止
配合Eperor模式,在centos、fedora、archlinux中,咱們能夠用systemd來管理uwsgi,首先,建立一個systemd service文件(/etc/systemd/system/emperor.uwsgi.service)
[Unit] Description=uWSGI Emperor After=syslog.target [Service] ExecStart=/root/uwsgi/uwsgi --emperor /etc/uwsgi/vassals Restart=always KillSignal=SIGQUIT Type=notify StandardError=syslog NotifyAccess=all [Install] WantedBy=multi-user.target
這樣咱們就能夠用systemd來管理uwsgi服務了。啓動服務:
$ systemctl start emperor.uwsgi.service
查詢服務運行狀態:
$ systemctl status emperor.uwsgi.service
中止服務
systemctl stop emperor.uwsgi.service
linux系統中,還有一種通用的方法,就是在init.d 或 rc.d 中加入啓動腳本,這種方式不夠智能,並且網上資料不少,在這裏暫不討論。
關於參數的具體使用,能夠閱讀官方文檔http://uwsgi-docs.readthedocs.org/en/latest/Options.html ,在這裏列出一些經常使用的參數: