• <noscript id="eom2a"><optgroup id="eom2a"></optgroup></noscript>
    <tt id="eom2a"><small id="eom2a"></small></tt>
    <input id="eom2a"></input>
  • <div id="eom2a"><small id="eom2a"></small></div>
    <td id="eom2a"><small id="eom2a"></small></td>
  • 您的位置:知識庫 ? Web前端

    配置Nginx+uwsgi更方便地部署python應用

    來源: observer專欄雜記  發布時間: 2011-01-03 21:59  閱讀: 2723 次  推薦: 3   原文鏈接   [收藏]  
    摘要:相比于PHP,Python應用的部署很麻煩,比較常用的方法有fcgi與wsgi,然而這兩種都很讓人頭痛。文章介紹了Nginx+uwsgi的簡便方法,來快速的部署Python應用。

      個人覺得php最方便的就是deployment了,只要把php文件丟到支持php的路徑里面,然后訪問那個路徑就能使用了;無論給主機添加多少php應用,只要把目錄改好就沒你的事了,完全不用關心php-cgi運行得如何,deployment極為方便。

      反觀python,部屬起來真是頭痛,常見的部署方法有:

    1. fcgi:用spawn-fcgi或者框架自帶的工具對各個project分別生成監聽進程,然后和http服務互動
    2. wsgi:利用http服務的mod_wsgi模塊來跑各個project

      無論哪種都很麻煩,apache的mod_wsgi配置起來很麻煩,內存占用還大,如果要加上nginx作為靜態頁面的服務器那就更麻煩了;反正我的應用基本上到后來都是是各個project各自為戰,且不說管理上的混亂,這樣對負載也是不利的,空閑的project和繁忙的project同樣需要占用內存,很容易出現站著茅坑不拉屎的現象。

      如果有個啥東東能像php-cgi一樣監聽同一端口,進行統一管理和負載平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才發現居然一直不知道有那么方便地統一部署工具。
      uWSGI,既不用wsgi協議也不用fcgi協議,而是自創了一個uwsgi的協議,據說該協議大約是fcgi協議的10倍那么快,有個比較見下圖

      uWSGI的主要特點如下,其中一些功能讓我感動得淚流滿面

    1. 超快的性能
    2. 低內存占用(實測為apache2的mod_wsgi的一半左右)
    3. 多app管理(終于不用冥思苦想下個app用哪個端口比較好了-.-)
    4. 詳盡的日志功能(可以用來分析app性能和瓶頸)
    5. 高度可定制(內存大小限制,服務一定次數后重啟等)

      總而言之uwgi是個部署用的好東東,正如uWSGI作者所吹噓的:

    If you are searching for a simple wsgi-only server, uWSGI is not for you, but if you are building a real (production-ready) app that need to be rock-solid, fast and easy to distribute/optimize for various load-average, you will pathetically and morbidly fall in love (we hope) with uWSGI.

      正式開工

      uwsgi的文檔雖然蠻多也很詳細,但是他們網站的排版真是讓人無語,粗粗看上去根本不知道文檔在哪里。其實是在這里:http://projects.unbit.it/uwsgi/wiki/Doc

      0.安裝uwsgi

      ubuntu有uwsgi的ppa

    add-apt-repository ppa:stevecrozz/ppa
    apt-get update
    apt-get install uwsgi

      1. 用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())
    application = app.wsgifunc()

      再比如django就是

    .......
    from django.core.handlers.wsgi import WSGIHandler
    application = WSGIHandler()

      然后運行uwsgi監聽9090,其中-w后跟模塊名,也就是剛才配置的myapp

    uwsgi -s :9090 -w myapp

      運行網站發現已經部署完成了。

      2. 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

      更多用法見文檔:http://projects.unbit.it/uwsgi/wiki/Doc

      3.為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服務了。

      4.實戰應用

      最初的設置完畢以后,再添加的應用,只需要在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版本,文檔缺失,各種兼容問題……大約是因為在python中,有個idea到實現出來實在是太過高效的關系吧,唉,被折騰死了。

    3
    0
    標簽:Nginx Python Web

    Web前端熱門文章

      Web前端最新文章

        最新新聞

          熱門新聞

            黄色网_免费在线黄色电影_黄色成人快播电影_伦理电影_黄色片