[线上环境部署Django,nginx+uwsgi 和nginx+gunicorn,这两种方案,应该如何选择?]

大家是采用的何种部署方式?

第一种,高并发稳定一点

我们公司使用的是nginx+gunicorn,主要是方便。性能可以从其他方面优化。

随便吧

我们用的是nginx supervisor gunicorn

Instagram由uwsgi转到gunicorn,建议用gunicorn,配置简单方便。

推荐 nginx supervisor gunicorn

配置简单,运维方便。

用的nginx+gunicorn方式,uwsgi没用过所以没法对比,就gunicorn的感受也来讲已经很快了,nginx处理掉了几乎全部的静态文件请求,实际上需要gunicorn再来处理的请求已经很少了。

gunicorn可以用Python文件直接配置,试用起来比较舒服。

我觉得这两种相差不多,根据你们相关的运维人员和开发人员的熟悉程度来决定。

现在的网站其实大部分处理的都是静态文件请求,除了诸如秒杀活动等等特定的业务,一般业务的请求量并不是很大。

所以你可以根据:1、你们当前的业务与以后可能会增加的业务;2、你们的运维人员的技能

来决定,哪个更熟悉就选哪个

[如何使用Nginx和uWSGI或Gunicorn在Ubuntu上部署Flask Web应用]

我在很多的博客中都看过有关Flask应用的部署,也有很多博主在开博后都记录了部署的教程,因为其中的坑可以说不少。一开始我在网上看到相比较与Ubuntu,CentOS因为更新少作为服务器的操作系统会更加稳定。所以在第一次购买云服务器时,我选择了CentOS,后来由于CentOS不同发行版的Nginx缘故,我又换成了Ubuntu的镜像

首先呢,我们先来了解下关于Web服务器与Web应用还有WSGI之间的联系

一、介绍

WSGI(Web Server Gateway Interface),翻译为Python web服务器网关接口,即Python的Web应用程序(如Flask)和Web服务器(如Nginx)之间的一种通信协议。也就是说,如果让你的Web应用在任何服务器上运行,就必须遵循这个协议。

那么实现WSGI协议的web服务器有哪些呢?就比如uWSGI与gunicorn。两者都可以作为Web服务器。可能你在许多地方看到的都是采用Nginx + uWSGI(或gunicorn)的部署方式。实际上,直接通过uWSGI或gunicorn直接部署也是可以让外网访问的,那你可能会说,那要Nginx何用?别急,那么接来下介绍另一个Web服务器——Nginx

Nginx作为一个高性能Web服务器,具有负载均衡、拦截静态请求、高并发...等等许多功能,你可能要问了,这些功能和使用Nginx + WSGI容器的部署方式有什么关系?

首先是负载均衡,如果你了解过OSI模型的话,其实负载均衡器就是该模型中4~7层交换机中的一种,它的作用是能够仅通过一个前端唯一的URL访问分发到后台的多个服务器,这对于并发量非常大的企业级Web站点非常有效。在实际应用中我们通常会让Nginx监听(绑定)80端口,通过多域名或者多个location分发到不同的后端应用。

其次是拦截静态请求,简单来说,Nginx会拦截到静态请求(静态文件,如图片),并交给自己处理。而动态请求内容将会通过WSGI容器交给Web应用处理;

Nginx还有其他很多的功能,这里便不一一介绍。那么前面说了,直接通过uWSGI或gunicorn也可以让外网访问到的,但是鉴于Nginx具有高性能、高并发、静态文件缓存、及以上两点、甚至还可以做到限流与访问控制,所以选择Nginx是很有必要的;

这里可以说明,如果你选择的架构是:Nginx + WSGI容器 + web应用,WSGI容器相当于一个中间件;如果选择的架构是uWSGI + web应用,WSGI容器则为一个web服务器

二、实际部署:

该篇部署的教程是在你已经购买好虚拟主机,并且已经搭建好开发环境的前提下进行的,如果你还没有搭建好开发环境,可以参考我写的文档:

普遍的部署方式都是通过让Nginx绑定80端口,并接受客户端的请求将动态内容的请求反向代理给运行在本地端口的uWSGI或者Gunicorn,所以既可以通过Nginx + uWSGI也可以通过Nginx + Gunicorn来部署Flask应用,这篇教程中都将一一介绍这两种方法

当然采用不同的WSGI容器,Nginx中的配置也会有所不同

1. Nginx + uWSGI:

1.1 配置uWSGI:

我们现在虚拟环境下安装好uWSGI:

(venv) $ pip install uwsgi

安装完成之后我们在项目的目录下(即你实际创建的Flask项目目录,在本文所指的项目目录都假设为/www/demo)创建以.ini为扩展名的配置文件。在设置与Nginx交互的时候有两种方式:

第一种是通过配置网络地址,第二种是通过本地的.socket文件进行通信。需要注意的是,不同的交互方式下,Nginx中的配置也会有所不同

如果采用的是第一种网络地址的方式,则将之前创建uwsgi.ini配置文件添加如下的配置内容:

[uwsgi]

socket = 127.0.0.1:8001 //与nginx通信的端口

chdir = /www/demo/ //你的Flask项目目录

wsgi-file = run.py

callable = app //run.py文件中flask实例化的对象名

processes = 4 //处理器个数

threads = 2 //线程个数

stats = 127.0.0.1:9191 //获取uwsgi统计信息的服务地址

这里的wsgi-file参数所指的run.py其实是启动文件,你也可以使用manage.py。不过我通常习惯创建一个这样的文件,可以直接运行该文件来启动项目:

from app import app

if __name__ == '__main__':

app.run()

保存好配置文件后,就可以通过如下的命令来启动应用了:

(venv) $ uwsgi uwsig.ini

如果你采用的是第二种本地socket文件的方式,则添加如下的配置内容:

[uwsgi]

socket = /www/demo/socket/nginx_uwsgi.socket //与nginx通信的socket文件

chdir = /www/demo/

wsgi-file = run.py

callable = app

processes = 4

threads = 2

stats = 127.0.0.1:9191

可以看到,其实与网络地址的配置方式只有socket参数的配置不同,在这里填写好路径名和文件名并启动uWSGI后,将会自动在改目录下生成nginx_uwsgi.socket文件,这个文件就是用来与Nginx交互的。

1.2 配置Nginx

首先我们来通过apt安装Nginx:

$ sudo apt-get install nginx

安装完成之后,我们cd到/etc/nginx/的目录下(可能由于不同系统导致不同的Nginx发行版缘故,目录有所差别,在此只针对Ubuntu中的发行版的Nginx),可以看到Nginx的所有配置文件。

其中nginx.conf文件为主配置文件,可以用来修改其全局配置;sites-available存放你的配置文件,但是在这里添加配置是不会应用到Nginx的配置当中,需要软连接到同目录下的sites-enabled当中。但是在我实际操作的过程中中,当我在sites-available修改好配置文件后,会自动更新到sites-enabled。如果没有的话,则需要像上述的操作那样,将修改好的配置文件软链接到sites-enabled当中

在上边说到,配置uWSGI有两种与Nginx交互的方式,那么选择不同的方式的话在Nginx的配置也会有所不同:

第一种:网络配置方式:

这里的proxy_set_header设置的三个参数的作用都是能够直接获得到客户端的IP,如果你感兴趣可以参考:Nginx中proxy_set_header 理解

用include uwsgi_params导入uWSGI所引用的参数,通过uwsgi_pass反向代理给在localhost:8001运行的uWSGI:

server {

listen 80; # 监听的端口号

root /www/demo; #Flask的项目目录

server_name xxx.xx.xxx.xxx; # 你的公网ip或者域名

location / {

proxy_set_header x-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $http_host;

include uwsgi_params;

uwsgi_pass localhost:8001;

}

# 配置static的静态文件:

location ~ ^\/static\/.*$ {

root /www/demo; # 注意!这里不需要再加/static了

}

}

在每次完Nginx配置文件内容后,需要通过如下的命令来重启Nginx:

$ nginx -s reload

第二种:socket文件方式:

与上边的配置内容大体相同,只是在配置uwsgi_pass不是反向代理给网络地址,而是通过socket文件进行交互,我们只需要指定之前设置的路径和文件名即可:

server {

listen 80;

root /www/demo;

server_name xxx.xx.xxx.xxx;

location / {

proxy_set_header x-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $http_host;

include uwsgi_params;

uwsgi_pass unix:/www/demo/socket/nginx_uwsgi.socket;

}

location ~ ^\/static\/.*$ {

root /www/demo;

}

}

2. Nginx + Gunicorn

2.1 配置Gunicorn:

首先先在虚拟环境下安装Gunicorn:

(venv) $ pip install gunicorn

安装完成后,我们来创建以.py结尾的配置文件,这里我参考了Jiyuankai的GitHub关于Gunicorn的配置文件内容:

from gevent import monkey

monkey.patch_all()

import multiprocessing

debug = True

loglevel = 'debug'

bind = '127.0.0.1:5000' //绑定与Nginx通信的端口

pidfile = 'log/gunicorn.pid'

logfile = 'log/debug.log'

workers = multiprocessing.cpu_count() * 2 + 1

worker_class = 'gevent' //默认为阻塞模式,最好选择gevent模式

需要注意的是要在配置文件的同层目录下创建log文件,否则运行gunicorn将报错。添加完配置内容并保存为gconfig.py文件后,我们就也可以通过gunicorn来运行Flask应用了:

(venv)$ gunicorn -c /www/demo/gconfig.py run:app

2.2 配置Nginx:

和uWSGI的任意一种配置方法类似,只是在location中的配置有所不同:

server {

listen 80;

root /www/demo;

server_name xxx.xx.xxx.xxx;

location / {

proxy_set_header x-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $http_host;

proxy_pass http://localhost:5000/; # gunicorn绑定的端口号

}

# 配置static的静态文件:

location ~ ^\/static\/.*$ {

root /www/demo;

}

}

通过Gunicorn的Nginx配置中,我们只需要通过proxy_pass参数反向代理给运行在http://localhost:5000/上的Gunicorn

三、守护进程

如果你采取如上的任意一种部署方式,在Nginx与uWSGI或Gunicorn同时运行,并且配置无误的状态下,那么你现在应该是可以通过你的公网ip或者域名访问到你的网站了。

但是还有一个问题,到目前为止,uWSGI和gunicorn都是直接通过命令行运行,并不能够在后台运行,也是当我们关闭了xShell(或者你使用的是Putty及其他SSH连接的软件),将无法再访问到你的应用。所以我们需要让uWSGI或gunicorn在后台运行,也就是所谓的daemon(守护进程)。

1. nohup:

如果你熟悉Linux命令,你应该知道在Linux中后台运行可以通过nohup命令,例如我们要让gunicorn在后台运行,我们只需要运行nohup命令:

(venv) $ nohup gunicorn -c gconfig.py run:app &

运行后你可以通过ps -e | grep gunicorn指令来查看到当前gunicorn的运行状态:

image

如果你选择的是uWSGI,同样也可以通过nohup命令来实现守护进程:

(venv) $ nohup uwsgi uwsgi.ini &

这样你就可以关闭连接服务器的终端,还能通过你的浏览器访问到你的Flask应用了!

2. supervisor

但是nohup运行的后台程序并不能够可靠的在后台运行,我们最好让我们的后台程序能够监控进程状态,还能在意外结束时自动重启,这就可以使用一个使用Python开发的进程管理程序supervisor。

参考:https://www.cnblogs.com/Dicky-Zhang/p/6171954.html

首先我们通过apt来安装supervisor:

$ sudo apt-get install supervisor

安装完成后,我们在/etc/supervisor/conf.d/目录下创建我们控制进程的配置文件,并以.conf结尾,这样将会自动应用到主配置文件当中,创建后添加如下的配置内容:

[program:demo]

command=/www/demo/venv/bin/gunicorn -c /pushy/blog/gconfig.py run:app

directory=/www/demo //项目目录

user=root

autorestart=true //设置自动重启

startretires=3 //重启失败3次

在上面的配置文件中,[program:demo]设置了进程名,这与之后操作进程的状态名称有关,为demo;command为进程运行的命令,必须使用绝对路径,并且使用虚拟环境下的gunicorn命令;user指定了运行进程的用户,这里设置为root

保存配置文件之后,我们需要通过命令来更新配置文件:

$ supervisorctl update

命令行将显示:demo: added process group,然后我们来启动这个demo进程:

$ supervisorctl start demo

当然你也直接在命令行输入supervisorctl进入supevisor的客户端,查看到当前的进程状态:

demo RUNNING pid 17278, uptime 0:08:51

通过stop命令便可以方便的停止该进程:

supervisor> stop demo

uwsgi模式_nginx+uwsgi 和nginx+gunicorn区别、如何部署相关推荐

  1. 【Flask】Nginx / Gunicorn入门:部署你的Flask项目

    什么是Nginx? 参考:Nginx入门 什么是反向代理呢? 我们很多人应该都用过淘宝,要知道每天同时连接到淘宝网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了,此时就出现了一个 ...

  2. Diango博客--11.Nginx + Gunicorn + Supervisor 方式部署

    文章目录 0.部署前准备 1.创建一个超级用户 2.更新 SQLite3 3.安装 Python3 .pip3.6以及 Pipenv 4.部署代码 5.使用 Gunicorn 6.启动 Nginx 服 ...

  3. python supervisor flask_Python Web 部署:Nginx Gunicorn Supervisor Flask部署笔记

    python web 部署 web开发中,各种语言争奇斗艳,web的部署方面,却没有太多的方式.简单而已,大概都是 nginx 做前端代理,中间 webservice 调用程序脚本.大概方式:ngin ...

  4. python supervisor flask_python web 部署:nginx + gunicorn + supervisor + flask 部署笔记

    分享一篇文章,原文来自:python web 部署. Python web 部署 web开发中,各种语言争奇斗艳,web的部署方面,却没有太多的方式.简单而已,大概都是 nginx 做前端代理,中间 ...

  5. 【Flask】Nginx+Gunicorn+Supervisor部署一个Flask项目:步骤总结

    为什么要使用gunicorn? Flask 作为一个 Web 框架,内置了一个 webserver, 但这自带的 Server 到底能不能用? 官网的介绍: While lightweight and ...

  6. uWSGI 和 nginx 的区别?

    uWSGI 和 nginx 的区别? (1 )uWSGI 是一个 Web 服务器,它实现了 WSGI 协议.uwsgi.http 等协议.Nginx 中HttpUwsgiModule 的作用是与 uW ...

  7. uwsgi模式_一篇就弄懂WSGI、uwsgi和uWSGI的区别

    引言 最近基于Django Web框架在开发一个后端项目,在Web Server和Django应用程序交互的过程中总会碰到本文题目提及到的几个概念,笔者特意花了点时间研究了下,为方便以后温习特在此记录 ...

  8. uwsgi模式_uWSGI模块

    导论 wsgi 全称web server gateway interface,wsgi不是服务器,也不是python模块,只是一种协议,描述web server如何和web application通信 ...

  9. flask gevent uwsgi nginx 联合高并发 部署

    1 python代码 /home/run.py from gevent import monkey monkey.patch_all()from flask import Flask app = Fl ...

最新文章

  1. 单片机开发项目全局变量太多怎么管理?
  2. 根据字符串选择类并完成类的初始化--方法二
  3. word从第3页开始设置页码为第一页_写论文、报告必会:快速让Word页码从第三页开始的方法...
  4. Python并发编程之:多进程
  5. putty WinScp 免密登录远程 Linux
  6. 外设驱动库开发笔记6:AD719x系列ADC驱动
  7. UIScrollView autolayout
  8. 05使用jmeter里调试一个下单接口
  9. php serialize error at offset,unserialize(): Error at offset出现的原因分析以及解决方法
  10. 《史记》记载的喝粥延命内容
  11. docker视频教程 假装听听 应该还行
  12. 基于微信小程序毕业论文选题系统(微信小程序毕业设计)
  13. 面试java工程师,面试官一般问什么问题?
  14. 计算机网络水平子系统布线图,综合布线七大子系统构成图
  15. 输出图形(循环程序,任意字符) 三角形、矩形、平行四边形、菱形
  16. 关于高效学习工作的几本书
  17. .join()用法 | python学习
  18. 微软正打造全新 Edge“Phoenix”浏览器?网友:画蛇添足?
  19. 优秀的 icon 的免费网站,看这篇就够了
  20. 用sublime搭建基于GoSublime+gocode+MarGo的下载SublimeGO开发环境

热门文章

  1. pyhton object is not subscriptable 解决
  2. mysql 分页优化
  3. 渗透知识-Struts2漏洞
  4. android ffmegp for_FFmpeg 编译for Android
  5. 孔兵 库卡机器人_名企零距离 专访库卡首席执行官 孔兵先生
  6. python写简单购物车_python简单的购物车程序(含代码)
  7. 光模块价格由带宽还是距离决定_光纤视频收发产品的光模块选型
  8. python动态导入检查是否存在_python动态导入模块、检查模块是否安装
  9. Linux之vim全选,全部复制,全部删除
  10. 使用FirefoxDriver时报错Make sure firefox is installed问题