PHP里,最方便的就是deployment了,只要把php文件丢到支持PHP的路径里面,然后访问那个路径就能使用了;无论给主机添加多少PHP应用,只要把目录改好就没你的事了,完全不用关心php-cgi运行得如何,deployment极为方便。

反观Python,部属起来真是头痛,常见的部署方法有:

◆fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务互动。

◆wsgi:利用http服务的mod_wsgi模块来跑各个project。

无论哪种都很麻烦,apache的mod_wsgi配置起来很麻烦,内存占用还大,如果要加上nginx作为静态页面的服务器那就更麻烦了;我的应用基本上到后来都是是各个project各自为战,且不说管理上的混乱,这样对负载也是不利的,空闲的project和繁忙的project同样需要占用内存。

如果Python中能有个什么东西像php-cgi一样监听同一端口,进行统一管理和负载平衡,那真是能省下大量的部署功夫。偶然看到了uWSGI,才发现居然一直不知道有那么方便地统一部署工具。uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的10倍那么快,有个比较见下图:

uWSGI的主要特点如下:

◆超快的性能。

◆低内存占用(实测为apache2的mod_wsgi的一半左右)。

◆多app管理。

◆详尽的日志功能(可以用来分析app性能和瓶颈)。

◆高度可定制(内存大小限制,服务一定次数后重启等)。

正式开工

uwsgi的文档虽然很多也很详细,这里是uwsgi的官方文档:http://projects.unbit.it/uwsgi/wiki/Doc。

1.安装uwsgi

ubuntu有uwsgi的ppa:

  1. add-apt-repository ppa:stevecrozz/ppa
  2. apt-get update
  3. apt-get install uwsgi

2. 用uwsgi代替mod_wsgi

Nginx的整体配置说来话长,这里不再多说,假设已经明白Nginx的基本配置,那么uwsgi就类似这么配置:

  1. location / {
  2. include uwsgi_params
  3. uwsgi_pass 127.0.0.1:9090
  4. }

这就是把所有url传给9090端口的uwsgi协议程序来互动。再到project目录建立myapp.py,使得application调用框架的wsgi接口,比如web.py就是:

  1. ......
  2. app = web.application(urls, globals())
  3. appapplication = app.wsgifunc()

再比如django就是:

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

然后运行uwsgi监听9090,其中-w后跟模块名,也就是刚才配置的myapp

  1. uwsgi -s :9090 -w myapp

运行网站发现已经部署完成了。

3.uwsgi的参数

以上是单个project的最简单化部署,uwsgi还是有很多令人称赞的功能的,例如:

并发4个线程:

  1. uwsgi -s :9090 -w myapp -p 4

主控制线程+4个线程:

  1. uwsgi -s :9090 -w myapp -M -p 4

执行超过30秒的client直接放弃:

  1. uwsgi -s :9090 -w myapp -M -p 4 -t 30

限制内存空间128M:

  1. uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128

服务超过10000个req自动respawn:

  1. uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000

后台运行等:

  1. 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”:

  1. uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost

然后必须配置virtualenv,virtualenv是Python的一个很有用的虚拟环境工具,这样安装:

  1. apt-get install Python-setuptools
  2. easy_install virtualenv

然后设置一个/多个app基准环境:

  1. virtualenv /var/www/myenv

应用环境,在此环境下安装的软件仅在此环境下有效:

  1. source /var/www/myenv/bin/activate
  2. pip install django
  3. pip install mako
  4. ...

最后配置nginx,注意每个站点必须单独占用一个server,同一server不同location定向到不同的应用不知为何总是失败,估计也算是一个bug。

  1. server {
  2. listen       80;
  3. server_name  app1.mydomain.com;
  4. location / {
  5. include uwsgi_params;
  6. uwsgi_pass 127.0.0.1:9090;
  7. uwsgi_param UWSGI_PYHOME /var/www/myenv;
  8. uwsgi_param UWSGI_SCRIPT myapp1;
  9. uwsgi_param UWSGI_CHDIR /var/www/myappdir1;
  10. }
  11. }
  12. server {
  13. listen       80;
  14. server_name  app2.mydomain.com;
  15. location / {
  16. include uwsgi_params;
  17. uwsgi_pass 127.0.0.1:9090;
  18. uwsgi_param UWSGI_PYHOME /var/www/myenv;
  19. uwsgi_param UWSGI_SCRIPT myapp2;
  20. uwsgi_param UWSGI_CHDIR /var/www/myappdir2;
  21. }
  22. }

这样,重启nginx服务,两个站点就可以共用一个uwsgi服务了。

5.实战应用

最初的设置完毕以后,再添加的应用,只需要在Nginx里面进行少量修改,无需重启uwsgi,就能立刻部署完毕。uwsgi自带了基于django的监控uwsgi运行状态的工具,就拿它来部署好了:

  1. server {
  2. listen 80;
  3. root   /var/www/django1.23;
  4. index  index.html index.htm;
  5. server_name uwsgiadmin.django.obmem.info;
  6. access_log  /var/log/nginx/django.access.log;
  7. location /media/ {
  8. root /var/www/django1.23/adminmedia;
  9. rewrite ^/media/(.*)$ /$1 break;
  10. }
  11. location / {
  12. include uwsgi_params;
  13. uwsgi_pass 127.0.0.1:9090;
  14. uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;
  15. uwsgi_param UWSGI_CHDIR /var/www/django1.23/uwsgiadmin;
  16. uwsgi_param UWSGI_SCRIPT uwsgiadmin_wsgi;
  17. }
  18. }

于是uwsgi的监控信息可以在http://uwsgiadmin.django.obmem.info看到(用户名密码都是admin)。再比如LBForum论坛程序的部署:根据安装说明安装完毕,再按部署说明修改完配置文件,然后只需修改nginx配置文件:

  1. server {
  2. listen 80;
  3. root   /var/www/django1.23;
  4. index  index.html index.htm;
  5. server_name lbforum.django.obmem.info;
  6. access_log  /var/log/nginx/django.access.log;
  7. location / {
  8. include uwsgi_params;
  9. uwsgi_pass 127.0.0.1:9090;
  10. uwsgi_param UWSGI_PYHOME /var/www/django1.23/vtenv;
  11. uwsgi_param UWSGI_CHDIR /var/www/django1.23/LBForum/sites/default;
  12. uwsgi_param UWSGI_SCRIPT lbforum_wsgi;
  13. }
  14. }

于是http://lbforum.django.obmem.info就是论坛程序了。

后记

虽然写出来寥寥几行,配置的时候我可吃尽了uwsgi的苦头,有些想当然的用法完全不能成立,–no-site参数一加上去其他都好使LBForum怎么都部署不了,一开始多站点公用uwsgi怎么都成功不了等等。

Python世界很有趣,一直会发现有趣的东西,但是Python世界也很折腾人,大部分东西都是dev版本,文档缺失,各种兼容问题。

原文地址:http://obmem.info/?p=703

uwsgi官网:http://projects.unbit.it/uwsgi/

快速部署Python应用:Nginx+uWSGI配置详解的更多相关文章

  1. Nginx 核心配置详解

    目录 Nginx 核心配置详解 Nginx 四层访问控制: Nginx账户认证功能: 自定义错误页面: 自定义访问日志: 检测文件是否存在: 长连接配置: 作为下载服务器配置: 作为上传服务器: 其他 ...

  2. Nginx的配置详解

    人无再少年,花有重开日——风城玫瑰 德里克·罗斯 Nginx是一款轻量级的HTTP服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的IO性能,时常用于服务端的反向代理和负载均衡. Ngin ...

  3. nginx.conf配置详解

    ######Nginx配置文件nginx.conf中文详解##### #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_ ...

  4. Nginx location配置详解

    上一篇博客Nginx配置详解已经说过了nginx 的基本配置情况,今天来详细讲述一下nginx的location的配置原则, location是根据Uri来进行不同的定位,location可以把网站的 ...

  5. 写给大忙人的nginx核心配置详解

    由于当前很多应该都是前后端分离了,同时大量的基于http的分布式和微服务架构,使得很多时候应用和不同项目组之间的系统相互来回调用,关系复杂.如果使用传统的做法,都在应用中进行各种处理和判断,不仅维护复 ...

  6. Nginx安装配置详解

    http://nginx.org/download/ 下载对应的Nginx 安装nginx之前需要安装依赖包 yum install gcc gcc-c++ zlib-devel pcre-devel ...

  7. nginx location 配置详解 【转载,整理】

    http://www.nginx.cn/115.html NGINX location 配置参考:http://www.cnblogs.com/zlingh/p/6288994.html https: ...

  8. Nginx基本属性配置详解

    1. Nginx服务的基本配置 1.1 用于调试进程和定位问题的配置项 是否以守护进程的方式运行nginx # 默认on daemon on|off; 是否以master/worker方式工作 # 默 ...

  9. 云服务器部署Python项目(nginx+uwsgi+mysql+项目)

    python项目部署到云服务器 关注公众号"轻松学编程"了解更多. 一.硬件准备 云服务器,系统ubuntu_16_04 . 注意:要在安全组中开放Http的80端口. 二.软件准 ...

随机推荐

  1. elipse图标注解

    Java中的访问修饰符(访问控制符)包括:public,protected,default,private.分别代表了不同的访问权限.如果省略,则被视为使用了默认的default作为访问修饰符.从字面 ...

  2. php 提交表单

    滴答…滴答…的雨,欢迎大家光临我的博客. 学习是快乐的,教育是枯燥的. 博客园   首页   博问   闪存     联系   订阅  管理 随笔-58  评论-2017  文章-5  trackba ...

  3. cocos2d-x 混合模式

    在OpenGL(ES),使用glBlendFunc函数实现实现混合模式,cocos2d-x中可以使用BlendFunc. 什么是颜色混合?简单来说就是将RGBA中的A,经行操作处理.具体一点,就是把某 ...

  4. POJ 3417 Network

    每条额外的边加入到图中,会导致树上一条路径成环,假设没有其余边,那么要将新图分成两部分,如果想删一条成环路径上的边,那么必须把这条额外边也删除. 因此每条额外边加入时,只需将环上的边+1.最后看看每条 ...

  5. js中call方法的使用介绍

    js call call 方法 请参阅 应用于:Function 对象 要求 版本 5.5 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, ...

  6. hdu_1728_逃离迷宫(bfs)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意:走迷宫,找最小的拐角 题解:对BFS有了新的理解,DFS+剪枝应该也能过,用BFS就要以拐 ...

  7. OpenCV——mixChannels函数

    mixChannels Copies specified channels from input arrays to the specified channels of output arrays. ...

  8. regular expression tutorial

    \d represent any number \D represents everything but a number \s represents any space \S Anything bu ...

  9. pureMVC java版搭建流程

    转自:http://blog.csdn.net/sutaizi/article/details/6588004 pureMVC 是一个轻量级的框架 它在 flex中非常流行(和cairngorm差不多 ...

  10. 二分查找(Binary Search)的基本实现

    关于二分查找法二分查找法主要是解决在"一堆数中找出指定的数"这类问题. 而想要应用二分查找法,这"一堆数"必须有一下特征: 1,存储在数组中2,有序排列 所以如 ...