天天看點

uWSGI + Nginx 部署

uWSGI + Nginx 部署 Flask Web 應用

建立Flask工程

這裡就用最簡單的HelloWorld,建立一個工程目錄:linuxidc,裡面包含以下檔案:

檔案名:linuxidc.py

代碼:

from flask import Flask

app = Flask(__name__)

@app.route('/')

def hello():

    return 'Hello World'

if __name__ == '__main__':

      app.run()

給項目目錄配置權限,nginx和uwsgi預設是以www-data使用者群組來運作:

 chown -R www-data:www-data /var/virenvs/myenv/myproject

 chmod -R 775 /var/virenvs/myenv/myproject

 建立uwsgi配置檔案

3)配置 uwsgi

在剛才建立的linuxidc目錄下建立一個uwsgi的xml配置檔案linuxidc_config.xml:

<uwsgi>

    <pythonpath>[你的工程的根目錄]</pythonpath>

    <module>[子產品名,這裡用linuxidc]</module>

    <callable>[因為app是啟動整個服務的入口,是以是app]</callable>

    <socket>0.0.0.0:8000</socket>      #注: 指定某個固定端口

    <master/>

    <processes>4</processes>                #注:跑幾個程序,這裡用4個程序

    <memory-report/>

</uwsgi>

4)配置 nginx

在/etc/nginx/sites-available/目錄下,建立一個站點檔案:site

server {

        listen 80;

        server_name www.linuxidc.com;

        location / {

                include uwsgi_params;

                uwsgi_pass  0.0.0.0:8000;  #注:這裡的端口8000和uwsgi的裡配的是同一個端口,因為nginx和uwsgi需要通過這個端口進行互動

        }

 }

然後用Linux的ln指令建立一個link到/etc/nginx/sites-enable/裡,link的名字也叫site,删除sites-enable目錄下的default的link。(很重要)

5)開始部署

啟動uwsgi,指令是 sudo uwsgi -x linuxidc_config.xml,會打出很多的字,如果沒有加載工程成功可以從打出的資訊中看出,然後不要關閉該Terminal,新打開一個Terminal,在裡面啟動nginx:sudo /etc/init.d/nginx start,然後在浏覽器裡通路localhost就可以看到“Hello World!” !

http://my.oschina.net/guol/blog/121418

基于python的web項目,常見的部署方法有:

      fcgi:用spawn-fcgi或者架構自帶的工具對各個project分别生成監聽程序,然後和http服務互動。

      wsgi:利用http服務的mod_wsgi子產品來跑各個project。

不過還有個uwsgi,它既不用wsgi協定也不用fcgi協定,而是自創了一個uwsgi的協定,據作者說該協定大約是fcgi協定的10倍那麼快。uWSGI的主要特點如下:

       超快的性能。

       低記憶體占用(實測為apache2的mod_wsgi的一半左右)。

       多app管理。

       詳盡的日志功能(可以用來分析app性能和瓶頸)。

       高度可定制(記憶體大小限制,服務一定次數後重新開機等)。

環境ubuntu 12.04 IP:10.1.6.79

安裝nginx

1 apt-getinstall nginx-full nginx-common
nginx配置/etc/nginx/sites-enabled/example

1

2

3

4

5

6

7

8

9

10

11

12

13

server {

        listen          80;

        server_name     10.1.6.79;##浏覽器通路

        access_log     /var/log/nginx/example_access.log;

        error_log      /var/log/nginx/example_error.log;

        root           /var/www/example;

        location / {

            uwsgi_pass      127.0.0.1:9001; ###uwsgi_pass 與uwsgi通信

            include         uwsgi_params;

            uwsgi_param     UWSGI_SCHEME $scheme;

            uwsgi_param     SERVER_SOFTWARE    nginx/$nginx_version;

        }

}

安裝uwsgi
1 apt-getinstall uwsgi uwsgi-plugin-python

    如果你想安裝所有的uwsgi插件,則可以安裝uwsgi-plugin-all軟體包

uwsgi配置/etc/uwsgi/apps-enabled/default.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<uwsgi>

    <plugin>python</plugin>

    <socket>127.0.0.1:9001</socket> ###uwsgi_pass 與nigix通信 

    <pythonpath>/var/www/example/app/</pythonpath>

    <app mountpoint="/">

        <script>wsgi_configuration_module</script>

    </app>

    <master/>

    <processes>4</processes>

    <reload-mercy>8</reload-mercy>

    <cpu-affinity>1</cpu-affinity>

    <max-requests>2000</max-requests>

    <limit-as>512</limit-as>

    <reload-on-as>256</reload-on-as>

    <reload-on-rss>192</reload-on-rss>

    <no-orphans/>

    <vacuum/>

</uwsgi>

    uwsgi配置檔案中的參數也可以在指令行通過uwsgi指定,配置檔案除了xml格式外,還可以寫成ini格式的,軟體包安裝完畢後在/usr/share/doc/uwsgi/examples/conffile目錄下會有一些xml和ini格式配置檔案的例子。

wsgi_configuration_module.py腳本内容

1

2

3

4

5

6

7

8

9

10

11

12

#!/usr/bin/python

importos

importsys

sys.path.append('/var/www/example/app')

os.environ['PYTHON_EGG_CACHE'] ='/var/www/example/.python-egg'

def application(environ, start_response):

    status ='200 OK'

    output ='Hello World!'

    response_headers = [('Content-type','text/plain'),

                    ('Content-Length', str(len(output)))]

    start_response(status, response_headers)

    return[output]

啟動uwsgi
1 uwsgi -x/etc/uwsgi/apps-enabled/default.xml --daemonize/var/log/uwsgi/app/default.log

uwsgi 的參數: 

    -M 開啟Master程序 

    -p 4 開啟4個程序 

    -s 使用的端口或者socket位址 

    -d 使用daemon的方式運作, 注意, 使用-d後, 需要加上log檔案位址, 比如-d /var/log/uwsgi.log 

    -R 10000 開啟10000個程序後, 自動respawn下 

    -t 30 設定30s的逾時時間, 逾時後, 自動放棄該連結 

    –limit-as 32 将程序的總記憶體量控制在32M 

    -x  使用配置檔案模式

并發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 

      除了直接用uwsgi指令啟動外,還可以用init.d下的腳本啟動,不過需先修改/etc/default/uwsgi中預設配置檔案的路徑,然後通過/etc/init.d/uwsgi start啟動

1

2

#INHERITED_CONFIG=/usr/share/uwsgi/conf/default.ini

INHERITED_CONFIG=/etc/uwsgi/apps-enabled/default.xml

啟動nginx
1 /etc/init.d/nginxstart

效果如下:

    python在國内用來做web還不多,雖然python也有一些web架構,不過目前來看文檔缺失、本身系統的穩定都還沒經過量和時間的考驗,要像PHP那樣大規模的火起來還需一段時間。

####################################################################

Nginx+uWsgi+web.py 搭建與簡單測試

Nginx+uWsgi+web.py 搭建與簡單測試

Nginx + uWsgi + web.py 效率真是不錯。

安裝uWsgi  

o 首先是下載下傳 http://projects.unbit.it/downloads/uwsgi-1.9.14.tar.gz

o 解壓 sudo python setup.py build

o 安裝 make

nginx和web.py的安裝就不多說

nginx配置

1 location / {

1 include uwsgi_params;

1 #uwsgi_pass 127.0.0.1:9002;

1  #對應uwsgi.ini配置的socket檔案

1 uwsgi_pass unix:/tmp/uwsgi.sock;

1 }

1 #靜态檔案通路

1 location /static/ {

1 if (-f $request_filename) {

1 rewrite ^/static/(.*)$ /static/$1 break;

1 }

1 }

基于web.py的腳本index.py

1 import web

1 urls = ("/.*", "hello")

1 app = web.application(urls, globals())

1 class hello:

1 def GET(self):

1 return 'Hello, world!'

1 #if __name__ == "__main__": #注意将改行注釋掉

1 application = app.wsgifunc()

uWsgi的配置

1 [uwsgi]

1 #socket = 127.0.0.1:9002

1 #用socket檔案方式

1 socket = /tmp/uwsgi.sock

1 chdir = /data/www/webpy/

1 processes = 8

1 threads = 2

1 master = true

1 module = index

1 ;pidfile = /data/uwsgi-bin/uwsgi.pid

1 ;listen = 128

1 #守護程序方式運作,并指明日志檔案

1 daemonize = /data/www/webpy/uwsgi.log

注意chdir指向程式目錄,module是主運作檔案,見上,加入pidfile後好像對性能有影響,是以這裡注釋掉。

運作 sudo uwsgi uwsgi.ini

測試

   測試使用的是apache的ab工具。ab -n1000 -c100 http://192.168.1.1:8080/,結果如下: 

拿php來測試下,同樣的伺服器,同樣的nginx,使用的是nginx + php-fpm fastcgi的模式。

看得出比PHP還是快了不少

 #!/bin/bash 

 wget -c http://rfyiamcool.googlecode.com/files/pcre-8.13.tar.gz 

 tar zxvf pcre-8.13.tar.gz 

 cd pcre-8.13/ 

 ./configure 

 make && make install 

 cd ../ 

 useradd www 

 wget -c http://rfyiamcool.googlecode.com/files/nginx-1.2.0.tar.gz 

 tar zxvf nginx-1.2.0.tar.gz 

 cd nginx-1.2.0 

 ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6 

 make && make install 

 cd .. 

 wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gz 

 cd uwsgi-1.3/ 

 python uwsgiconfig.py --build 

 \cp nginx/uwsgi_params /usr/local/nginx/conf/ -f 

 vi /usr/local/nginx/conf/nginx.conf 

 server { 

         listen        80; 

         server_name localhost; 

         location / { 

             root  /usr/local/nginx/html; 

             include uwsgi_params; 

             uwsgi_pass 127.0.0.1:8000; 

         } 

  } 

 /usr/local/nginx/sbin/nginx 

 cd /usr/local/nginx/html 

 vi uwsgi.xml 

 <uwsgi> 

 <socket>127.0.0.1:8000</socket> 

 <module>myuwsgi</module> 

 <master /> 

 <pythonpath>/usr/local/nginx/html</pythonpath> 

 <processes>2</processes> 

 </uwsgi> 

 vi   web.py 

 #!/usr/bin/env python 

 import os 

 import web 

 urls = ('/(.*)', 'hello') 

 app = web.application(urls, globals()) 

 class hello: 

     def GET(self, name): 

         if not name: 

             name = "World" 

         return "Hello" + name + "!" 

 appapplication = app.wsgifunc() 

 啟動 

 /usr/local/uwsgi-1.3/uwsgi -x /usr/local/nginx/html/uwsgi.xml --daemonize /usr/local/nginx/html/uwsgi.error.log 

 停止uWSGI 

 killall -9 uwsgi 

 排錯 

 netstat -an|grep -E '(8000|80)' 

 ps aux|grep uwsgi 

http://my.oschina.net/guol/blog/121418

基于python的web項目,常見的部署方法有:

      fcgi:用spawn-fcgi或者架構自帶的工具對各個project分别生成監聽程序,然後和http服務互動。

      wsgi:利用http服務的mod_wsgi子產品來跑各個project。

不過還有個uwsgi,它既不用wsgi協定也不用fcgi協定,而是自創了一個uwsgi的協定,據作者說該協定大約是fcgi協定的10倍那麼快。uWSGI的主要特點如下:

       超快的性能。

       低記憶體占用(實測為apache2的mod_wsgi的一半左右)。

       多app管理。

       詳盡的日志功能(可以用來分析app性能和瓶頸)。

       高度可定制(記憶體大小限制,服務一定次數後重新開機等)。

環境ubuntu 12.04 IP:10.1.6.79

安裝nginx

1 apt-getinstall nginx-full nginx-common
nginx配置/etc/nginx/sites-enabled/example

1

2

3

4

5

6

7

8

9

10

11

12

13

server {

        listen          80;

        server_name     10.1.6.79;##浏覽器通路

        access_log     /var/log/nginx/example_access.log;

        error_log      /var/log/nginx/example_error.log;

        root           /var/www/example;

        location / {

            uwsgi_pass      127.0.0.1:9001; ###uwsgi_pass 與uwsgi通信

            include         uwsgi_params;

            uwsgi_param     UWSGI_SCHEME $scheme;

            uwsgi_param     SERVER_SOFTWARE    nginx/$nginx_version;

        }

}

安裝uwsgi
1 apt-getinstall uwsgi uwsgi-plugin-python

    如果你想安裝所有的uwsgi插件,則可以安裝uwsgi-plugin-all軟體包

uwsgi配置/etc/uwsgi/apps-enabled/default.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<uwsgi>

    <plugin>python</plugin>

    <socket>127.0.0.1:9001</socket> ###uwsgi_pass 與nigix通信 

    <pythonpath>/var/www/example/app/</pythonpath>

    <app mountpoint="/">

        <script>wsgi_configuration_module</script>

    </app>

    <master/>

    <processes>4</processes>

    <reload-mercy>8</reload-mercy>

    <cpu-affinity>1</cpu-affinity>

    <max-requests>2000</max-requests>

    <limit-as>512</limit-as>

    <reload-on-as>256</reload-on-as>

    <reload-on-rss>192</reload-on-rss>

    <no-orphans/>

    <vacuum/>

</uwsgi>

    uwsgi配置檔案中的參數也可以在指令行通過uwsgi指定,配置檔案除了xml格式外,還可以寫成ini格式的,軟體包安裝完畢後在/usr/share/doc/uwsgi/examples/conffile目錄下會有一些xml和ini格式配置檔案的例子。

wsgi_configuration_module.py腳本内容

1

2

3

4

5

6

7

8

9

10

11

12

#!/usr/bin/python

importos

importsys

sys.path.append('/var/www/example/app')

os.environ['PYTHON_EGG_CACHE'] ='/var/www/example/.python-egg'

def application(environ, start_response):

    status ='200 OK'

    output ='Hello World!'

    response_headers = [('Content-type','text/plain'),

                    ('Content-Length', str(len(output)))]

    start_response(status, response_headers)

    return[output]

啟動uwsgi
1 uwsgi -x/etc/uwsgi/apps-enabled/default.xml --daemonize/var/log/uwsgi/app/default.log

uwsgi 的參數: 

    -M 開啟Master程序 

    -p 4 開啟4個程序 

    -s 使用的端口或者socket位址 

    -d 使用daemon的方式運作, 注意, 使用-d後, 需要加上log檔案位址, 比如-d /var/log/uwsgi.log 

    -R 10000 開啟10000個程序後, 自動respawn下 

    -t 30 設定30s的逾時時間, 逾時後, 自動放棄該連結 

    –limit-as 32 将程序的總記憶體量控制在32M 

    -x  使用配置檔案模式

并發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 

      除了直接用uwsgi指令啟動外,還可以用init.d下的腳本啟動,不過需先修改/etc/default/uwsgi中預設配置檔案的路徑,然後通過/etc/init.d/uwsgi start啟動

1

2

#INHERITED_CONFIG=/usr/share/uwsgi/conf/default.ini

INHERITED_CONFIG=/etc/uwsgi/apps-enabled/default.xml

啟動nginx
1 /etc/init.d/nginxstart

效果如下:

    python在國内用來做web還不多,雖然python也有一些web架構,不過目前來看文檔缺失、本身系統的穩定都還沒經過量和時間的考驗,要像PHP那樣大規模的火起來還需一段時間。

####################################################################

Nginx+uWsgi+web.py 搭建與簡單測試

Nginx+uWsgi+web.py 搭建與簡單測試

Nginx + uWsgi + web.py 效率真是不錯。

安裝uWsgi  

o 首先是下載下傳 http://projects.unbit.it/downloads/uwsgi-1.9.14.tar.gz

o 解壓 sudo python setup.py build

o 安裝 make

nginx和web.py的安裝就不多說

nginx配置

1 location / {

1 include uwsgi_params;

1 #uwsgi_pass 127.0.0.1:9002;

1  #對應uwsgi.ini配置的socket檔案

1 uwsgi_pass unix:/tmp/uwsgi.sock;

1 }

1 #靜态檔案通路

1 location /static/ {

1 if (-f $request_filename) {

1 rewrite ^/static/(.*)$ /static/$1 break;

1 }

1 }

基于web.py的腳本index.py

1 import web

1 urls = ("/.*", "hello")

1 app = web.application(urls, globals())

1 class hello:

1 def GET(self):

1 return 'Hello, world!'

1 #if __name__ == "__main__": #注意将改行注釋掉

1 application = app.wsgifunc()

uWsgi的配置

1 [uwsgi]

1 #socket = 127.0.0.1:9002

1 #用socket檔案方式

1 socket = /tmp/uwsgi.sock

1 chdir = /data/www/webpy/

1 processes = 8

1 threads = 2

1 master = true

1 module = index

1 ;pidfile = /data/uwsgi-bin/uwsgi.pid

1 ;listen = 128

1 #守護程序方式運作,并指明日志檔案

1 daemonize = /data/www/webpy/uwsgi.log

注意chdir指向程式目錄,module是主運作檔案,見上,加入pidfile後好像對性能有影響,是以這裡注釋掉。

運作 sudo uwsgi uwsgi.ini

測試

   測試使用的是apache的ab工具。ab -n1000 -c100 http://192.168.1.1:8080/,結果如下: 

拿php來測試下,同樣的伺服器,同樣的nginx,使用的是nginx + php-fpm fastcgi的模式。

看得出比PHP還是快了不少

 #!/bin/bash 

 wget -c http://rfyiamcool.googlecode.com/files/pcre-8.13.tar.gz 

 tar zxvf pcre-8.13.tar.gz 

 cd pcre-8.13/ 

 ./configure 

 make && make install 

 cd ../ 

 useradd www 

 wget -c http://rfyiamcool.googlecode.com/files/nginx-1.2.0.tar.gz 

 tar zxvf nginx-1.2.0.tar.gz 

 cd nginx-1.2.0 

 ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-ipv6 

 make && make install 

 cd .. 

 wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gz 

 cd uwsgi-1.3/ 

 python uwsgiconfig.py --build 

 \cp nginx/uwsgi_params /usr/local/nginx/conf/ -f 

 vi /usr/local/nginx/conf/nginx.conf 

 server { 

         listen        80; 

         server_name localhost; 

         location / { 

             root  /usr/local/nginx/html; 

             include uwsgi_params; 

             uwsgi_pass 127.0.0.1:8000; 

         } 

  } 

 /usr/local/nginx/sbin/nginx 

 cd /usr/local/nginx/html 

 vi uwsgi.xml 

 <uwsgi> 

 <socket>127.0.0.1:8000</socket> 

 <module>myuwsgi</module> 

 <master /> 

 <pythonpath>/usr/local/nginx/html</pythonpath> 

 <processes>2</processes> 

 </uwsgi> 

 vi   web.py 

 #!/usr/bin/env python 

 import os 

 import web 

 urls = ('/(.*)', 'hello') 

 app = web.application(urls, globals()) 

 class hello: 

     def GET(self, name): 

         if not name: 

             name = "World" 

         return "Hello" + name + "!" 

 appapplication = app.wsgifunc() 

 啟動 

 /usr/local/uwsgi-1.3/uwsgi -x /usr/local/nginx/html/uwsgi.xml --daemonize /usr/local/nginx/html/uwsgi.error.log 

 停止uWSGI 

 killall -9 uwsgi 

 排錯 

 netstat -an|grep -E '(8000|80)' 

 ps aux|grep uwsgi