重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
WSGI是為python語言定義的通用網關接口,它承擔python web框架(django、flask、web.py等)和web服務器(nginx、apache、lighttpd等)之間的中間層。
瀏覽器 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。
1 uWSGI的安裝uWSGI是用C語言寫的高性能WSGI服務器,安裝uWSGI前我們需要安裝Python和C編譯器(GCC)。推薦使用python包管理器pip安裝uWSGI。
#安裝最新穩定版 pip install uWSGI #也可以安裝長期支持版(LTS版本) #pip install http://projects.unbit.it/downloads/uwsgi-lts.tar.gz
在ubuntu下可以使用apt-get來安裝
apt-get install uwsgi
在fedora、redhat、centos下使用yum安裝
yum groupinstall "Development Tools" yum install python
編譯安裝,從github下載uwsgi代碼,cd到目錄下
python uwsgiconfig.py --build 2 測試uwsgi是否安裝成功
在終端中輸入以下命令查看uwsgi的版本號,如果輸出正常,說明uswgi已安裝成功
$ uwsgi --version 2.0.11.1
我們可以編寫一個簡單的wsgi應用來測試uwsgi是否被安裝成功,首先創建一個test.py文件:
# 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:
uwsgi --http :8000 --wsgi-file test.py
參數中,http :8000表示使用http協議,端口號為8000,wigi-file則表示要運行的wsgi應用程序文件。uwsgi運行后打開瀏覽器,訪問http://127.0.0.1:8000/ ,或者是相應服務器地址的8000端口,就可以看到hello world 頁面了。
上面的例子中,我們用瀏覽器直接訪問了uwsgi運行的python程序(只有一個入口函數的wsgi測試應用test.py),其訪問結構如下所示。
瀏覽器 <-> uWSGI <-> Python
上述方式運行uWSGI服務的過程中,可以使用CTRL+C即可停止服務,在后續的章節中會講到自動管理和部署。
3 nginx和django的配置nginx和django的安裝不是本文的重點,故在此略去,只討論配置部分。在這里,我們要實現的效果如下:
瀏覽器 <-> nginx <-> uWSGI <-> Django(python) uwsgi_params 配置文件
uWSGI使用的協議不完全是標準的WSGI協議,我們需要從Github下載uwsgi_paraments配置文件,并將該文件拷貝到項目路徑中(例如:/user/home/pengquanxin/projects/mysite1/)。
Nginx服務器配置接下來,要配置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 4 啟動服務
在啟動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站點了。
5 使用ini配置文件跑uWSGI到這里,我們已經把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 6 管理uwsgi Emperor模式
uWSGI的Epreror模式可以用來管理機器上部署的uwsgi服務,在這種模式下,會有一個特殊的進程(皇帝)對其它部署的服務(諸侯)進行監視。我們將所有配置文件(ini或xml文件,如上一節中的mysite.uwsgi.ini)統一放到一個文件夾(如:/etc/uwsgi/vassals)中,然后啟動Emperor模式:
uwsgi --emperor /etc/uwsgi/vassals
這樣,就會自動讀取文件夾中的配置文件,并自動監控這些uwsgi服務: - 檢測文件夾中有新的配置文件時,會啟動新的uwsgi服務實例 - 檢測到一個配置文件發生改變,會自動重啟該服務 - 檢測到一個配置文件被移除,則自動停止該服務 - 如果一個服務死了(諸侯),皇帝進程會重啟該服務 - 如果監控進程(皇帝)死了,所有服務(諸侯)都會停止
用systemd管理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 中加入啟動腳本,這種方式不夠智能,而且網上資料很多,在這里暫不討論。
7 常用參數和選項關于參數的具體使用,可以閱讀官方文檔http://uwsgi-docs.readthedocs.org/en/latest/Options.html,在這里列出一些常用的參數:
chdir 項目目錄 home virtualenv目錄(如沒有運行virtualenv虛擬環境,則無需設置) socket 套接字文件或TCP套接字,例如:site1.uwsgi.sock 或 127.0.0.1:8000 uid 用戶id gid 用戶組id processes 工作進程數 harakiri 進程超過該時間未響應就重啟該進程(默認單位為秒) module 要啟動的wsgi模塊入口,如:mysite.wsgi:application ini 指定ini配置文件 xml 指定xml配置文件(與ini類似) file 指定要運行的wsgi程序文件,如:test.py emperor Emperor模式 so-keepalive 開啟TCP KEEPALIVE(unix套接字方式下無效) vacuum 退出時清空環境