设为首页 收藏本站
查看: 876|回复: 0

[经验分享] python 使用Nginx和uWSGI来运行Python应用

[复制链接]

尚未签到

发表于 2017-12-22 22:47:49 | 显示全部楼层 |阅读模式
  参考:http://zmrenwu.com/post/20/
  uWSGI是一个Web应用服务器,它具有应用服务器,代理,进程管理及应用监控等功能。它支持WSGI协议,同时它也支持自有的uWSGI协议,该协议据说性能非常高,而且内存占用率低,为mod_wsgi的一半左右,我没有实测过。它还支持多应用的管理及应用的性能监控。虽然uWSGI本身就可以直接用来当Web服务器,但一般建议将其作为应用服务器配合Nginx一起使用,这样可以更好的发挥Nginx在Web端的强大功能。本文我们就来介绍如何搭建uWSGI+Ngnix环境来运行Python应用。

安装uWSGI
  pip install uwsgi
  让我们来写个Hello World的WSGI应用,并保存在”server.py”文件中:
  

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中运行它,执行命令:
  

uwsgi --http :9090 --wsgi-file server.py  

  然后打开浏览器,访问”http://localhost:9090″,你就可以看到”Hello World!”字样了。
  上面的命令中”- -http”参数指定了HTTP监听地址和端口,”- -wsgi-file”参数指定了WSGI应用程序入口,uWSGI会自动搜寻名为”application”的应用对象并调用它。
  更进一步,uWSGI可以支持多进程和多线程的方式启动应用,也可以监控应用的运行状态。我们将启动的命令改为:
  

$ uwsgi --http :9090 --wsgi-file server.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191  

  执行它后,uWSGI将启动4个应用进程,每个进程有2个线程,和一个master主进程(监控其他进程状态,如果有进程死了,则重启)。同时,你可以访问”127.0.0.1:9191″来获取JSON格式的应用运行信息,uWSGI还提供了工具命令”uwsgitop”来像top一样监控应用运行状态,你可以用pip来安装它。
  上面的命令参数太多了,我们可以将参数写在配置文件里,启动uWSGI时指定配置文件即可。配置文件可以是键值对的格式,也可以是XML,YAML格式,这里我们使用键值对的格式。让我们创建一个配置文件”myapp.ini”:
  

[uwsgi]  
http
=:9090  
wsgi
-file=server.py  
master
=true  
processes
=4  
threads
=2  
stats
=127.0.0.1:9191  

  然后就可以将启动命令简化为:
  

$ uwsgi myapp.ini  


配置Nginx
  Nginx的安装可以参考这篇文章,文本采用的环境就是Ubuntu Linux,对于其他系统如Mac,基本上差不太多
  首先,我们将uWSGI的HTTP端口监听改为socket端口监听,即将配置文件中的”http”项去掉,改为”socket”项:
  

[uwsgi]  
socket
=127.0.0.1:3031  
wsgi
-file=server.py  
master
=true  
processes
=4  
threads
=2  
stats
=127.0.0.1:9191  

  然后,打开Nginx的配置文件,Ubuntu上默认是”/etc/nginx/sites-enabled/default”文件,将其中的根路径部分配置为:
  

location / {  include uwsgi_params;
  uwsgi_pass
127.0.0.1:3031;  
}
  

  这段配置表明Nginx会将收到的所有请求都转发到”127.0.0.1:3031″端口上,即uWSGI服务器上。现在让我们重启Nginx,并启动uWSGI服务器:
  

$ sudo service nginx restart  
$ uwsgi myapp.ini
  

  访问”http://localhost”,我们会再次看到”Hello World!”。

运行Flask应用
  其实很简单,只要将上例中server.py的内容改为Flask应用即可,当然你需要先把Flask包安装好:
  

from flask import Flask  
application
= Flask(__name__)  
@application.route(
'/')  

def index():return '<h1>Hello World</h1>'  

  很多人习惯将Flask应用对象取名为”app”,但是WSGI标准是”application”。uWSGI提供了一个功能,可以指定应用对象,方法就是在配置文件中加上”callable”项:
  

[uwsgi]  
...
  
callable
=app  

  现在,我们的Flask应用就可以使用”app”作为对象名了
  

from flask import Flask  
app
= Flask(__name__)  
@app.route(
'/')  

def index():return '<h1>Hello World</h1>'  


使用Python虚拟环境
  我们永远都是建议采用虚拟环境来避免应用间冲突,uWSGI可以非常容易做到这点,就是在配置文件中加上”virtualenv”项:
  

[uwsgi]  
...
  
virtualenv=
/home/bjhee/virtualenv  


部署多个应用
  一个Nginx中,可以同时运行多个应用,不一定是Python的应用。我们期望通过不同的路径来路由不同的应用,因此就不能像上例那样直接修改根目录的配置。假设我们希望通过”http://localhost/myapp”来访问我们的应用,首先要在Nginx的配置文件中,加入下面的内容:
  

location /myapp {  include uwsgi_params;
  uwsgi_param SCRIPT_NAME
/myapp;  uwsgi_pass
127.0.0.1:3031;  
}
  

  这里我们定义了一个uWSGI参数”SCRIPT_NAME”,值为应用的路径”/myapp”。接下来,在uWSGI的启动配置中,去掉”wsgi-file”项,并加上:
  

[uwsgi]  
...
  
mount
=/myapp=server.py  
manage
-script-name=true  

  “mount”参数表示将”/myapp”地址路由到”server.py”中,”manage-script-name”参数表示启用之前在Nginx里配置的”SCRIPT_NAME”参数。再次重启Nginx和uWSGI,你就可以通过”http://localhost/myapp”来访问应用了。

补充内容
  上面的所有例子中,我们是通过”127.0.0.1:3031″Socket端口来连接Nginx和uWSGI的,其实我们也可以采用socket文件的方式,这样可以不用写死端口。在uWSGI的启动配置中,我们要修改”socket”项:
  

[uwsgi]  
socket
=/tmp/uwsgi.sock  
...
  

  启动uWSGI服务器后,它会自动创建一个”/tmp/uwsgi.sock”文件。然后让我们修改Nginx配置文件,将”uwsgi_pass”配置项改为文件:
  

location /myapp {  include uwsgi_params;
  uwsgi_param SCRIPT_NAME
/myapp;  uwsgi_pass unix:
/tmp/uwsgi.sock;  
}
  

  重启Nginx服务器即可。这里我开始一直没跑通,研究了好久才发现,Nginx的用户(默认的www-date:adm),必须要对该文件有读写的权限才行。因为运行uWSGI的用户与运行Nginx的用户不一样,而”/tmp/uwsgi.sock”是由uWSGI的用户创建的,导致Nginx没有足够的权限。如果朋友们也遇到同样的问题,那就只能chmod了。
  另外,还是要提一下”.egg”包的解压缩临时目录,我们在介绍mod_wsgi的最后提到过,在uWSGI应用中也一样,Linux上默认是在用户主目录下,比如”/home/bjhee/.python-eggs”。你可以通过设置系统环境变量”PYTHON_EGG_CACHE”来改变它。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-426992-1-1.html 上篇帖子: nginx提示Job for nginx.service failed because the control的问题 下篇帖子: Nginx错误页面优雅显示
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表