在PHP裏,最方便的就是deployment了,只要把php文件丟到支持PHP的路徑裏面,而後訪問那個路徑就能使用了;不管給主機添加多少PHP應用,只要把目錄改好就沒你的事了,徹底不用關心php-cgi運行得如何,deployment極爲方便。php
反觀Python,部屬起來真是頭痛,常見的部署方法有:html
◆fcgi:用spawn-fcgi或者框架自帶的工具對各個project分別生成監聽進程,而後和http服務互動。nginx
◆wsgi:利用http服務的mod_wsgi模塊來跑各個project。web
不管哪一種都很麻煩,apache的mod_wsgi配置起來很麻煩,內存佔用還大,若是要加上nginx做爲靜態頁面的服務器那就更麻煩了;個人應用基本上到後來都是是各個project各自爲戰,且不說管理上的混亂,這樣對負載也是不利的,空閒的project和繁忙的project一樣須要佔用內存。apache
若是Python中能有個什麼東西像php-cgi同樣監聽同一端口,進行統一管理和負載平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才發現竟然一直不知道有那麼方便地統一部署工具。uWSGI,既不用wsgi協議也不用fcgi協議,而是自創了一個uwsgi的協議,聽說該協議大約是fcgi協議的10倍那麼快,有個比較見下圖:django
uWSGI的主要特色以下:ubuntu
◆超快的性能。服務器
◆低內存佔用(實測爲apache2的mod_wsgi的一半左右)。併發
◆多app管理。app
◆詳盡的日誌功能(能夠用來分析app性能和瓶頸)。
◆高度可定製(內存大小限制,服務必定次數後重啓等)。
正式開工
uwsgi的文檔雖然不少也很詳細,這裏是uwsgi的官方文檔:http://projects.unbit.it/uwsgi/wiki/Doc。
1.安裝uwsgi
ubuntu有uwsgi的ppa:
- add-apt-repository ppa:stevecrozz/ppa
- apt-get update
- apt-get install uwsgi
2. 用uwsgi代替mod_wsgi
Nginx的總體配置說來話長,這裏再也不多說,假設已經明白Nginx的基本配置,那麼uwsgi就相似這麼配置:
- location / {
- include uwsgi_params
- uwsgi_pass 127.0.0.1:9090
- }
這就是把全部url傳給9090端口的uwsgi協議程序來互動。再到project目錄創建myapp.py,使得application調用框架的wsgi接口,好比web.py就是:
- ......
- app = web.application(urls, globals())
- appapplication = app.wsgifunc()
再好比django就是:
- .......
- from django.core.handlers.wsgi import WSGIHandler
- application = WSGIHandler()
而後運行uwsgi監聽9090,其中-w後跟模塊名,也就是剛纔配置的myapp
- uwsgi -s :9090 -w myapp
運行網站發現已經部署完成了。
3.uwsgi的參數
以上是單個project的最簡單化部署,uwsgi仍是有不少使人稱讚的功能的,例如:
併發4個線程:
- uwsgi -s :9090 -w myapp -p 4
主控制線程+4個線程:
- uwsgi -s :9090 -w myapp -M -p 4
執行超過30秒的client直接放棄:
- uwsgi -s :9090 -w myapp -M -p 4 -t 30
限制內存空間128M:
- uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128
服務超過10000個req自動respawn:
- uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000
後臺運行等:
- uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log
4.爲uwsgi配置多個站點
爲了讓多個站點共享一個uwsgi服務,必須把uwsgi運行成虛擬站點:去掉「-w myapp」加上」–vhost」:
- uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost
而後必須配置virtualenv,virtualenv是Python的一個頗有用的虛擬環境工具,這樣安裝:
- apt-get install Python-setuptools
- easy_install virtualenv
而後設置一個/多個app基準環境:
- virtualenv /var/www/myenv
應用環境,在此環境下安裝的軟件僅在此環境下有效:
- source /var/www/myenv/bin/activate
- pip install django
- pip install mako
- ...
最後配置nginx,注意每一個站點必須單獨佔用一個server,同一server不一樣location定向到不一樣的應用不知爲什麼老是失敗,估計也算是一個bug。
- server {
- listen 80;
- server_name app1.mydomain.com;
- location / {
- include uwsgi_params;
- uwsgi_pass 127.0.0.1:9090;
- uwsgi_param UWSGI_PYHOME /var/www/myenv;
- uwsgi_param UWSGI_SCRIPT myapp1;
- uwsgi_param UWSGI_CHDIR /var/www/myappdir1;
- }
- }
- server {
- listen 80;
- server_name app2.mydomain.com;
- location / {
- include uwsgi_params;
- uwsgi_pass 127.0.0.1:9090;
- uwsgi_param UWSGI_PYHOME /var/www/myenv;
- uwsgi_param UWSGI_SCRIPT myapp2;
- uwsgi_param UWSGI_CHDIR /var/www/myappdir2;
- }
- }
這樣,重啓nginx服務,兩個站點就能夠共用一個uwsgi服務了。
5.實戰應用
最初的設置完畢之後,再添加的應用,只須要在Nginx裏面進行少許修改,無需重啓uwsgi,就能馬上部署完畢。uwsgi自帶了基於django的監控uwsgi運行狀態的工具,就拿它來部署好了:
- server {
- listen 80;
- root /var/www/django1.23;
- index index.html index.htm;
- server_name uwsgiadmin.django.obmem.info;
- access_log /var/log/nginx/django.access.log;
- location /media/ {
- root /var/www/django1.23/adminmedia;
- rewrite ^/media/(.*)$ /$1 break;
- }
- location / {
- include uwsgi_params;
- uwsgi_pass 127.0.0.1:9090;
- uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;
- uwsgi_param UWSGI_CHDIR /var/www/django1.23/uwsgiadmin;
- uwsgi_param UWSGI_SCRIPT uwsgiadmin_wsgi;
- }
- }
因而uwsgi的監控信息能夠在http://uwsgiadmin.django.obmem.info看到(用戶名密碼都是admin)。再好比LBForum論壇程序的部署:根據安裝說明安裝完畢,再按部署說明修改完配置文件,而後只需修改nginx配置文件:
- server {
- listen 80;
- root /var/www/django1.23;
- index index.html index.htm;
- server_name lbforum.django.obmem.info;
- access_log /var/log/nginx/django.access.log;
- location / {
- include uwsgi_params;
- uwsgi_pass 127.0.0.1:9090;
- uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;
- uwsgi_param UWSGI_CHDIR /var/www/django1.23/LBForum/sites/default;
- uwsgi_param UWSGI_SCRIPT lbforum_wsgi;
- }
- }
因而http://lbforum.django.obmem.info就是論壇程序了。
後記
雖然寫出來寥寥幾行,配置的時候我可吃盡了uwsgi的苦頭,有些想固然的用法徹底不能成立,–no-site參數一加上去其餘都好使LBForum怎麼都部署不了,一開始多站點公用uwsgi怎麼都成功不了等等。
Python世界頗有趣,一直會發現有趣的東西,可是Python世界也很折騰人,大部分東西都是dev版本,文檔缺失,各類兼容問題。
原文地址:http://obmem.info/?p=703
uwsgi官網:http://projects.unbit.it/uwsgi/