@html
所谓WSGI
.
WSGI是Web服务器网关接口,它是一个规范,描述了Web服务器如何与Web应用程序通讯,以及如何与Web应用程序连接在一块儿处理一个请求(接收请求、处理请求、响应请求).
.
基于wsgi运行的框架有Bottle、Django、Flask,用于解析动态HTTP请求.
.
---------⬇️
支持WSGI的服务器
.
wsgiref
Python自带的服务器.
.
Gunicorn
用于Linux的python wsgi Http服务器,经常使用于各类Django、Flask结合部署服务器.
.
mode_wsgi
实现了Apache与wsgi应用程序的结合.
.
uWSGI
C语言开发,快速,自我修复,开发人员友好的WSGI服务器,用于Python Web应用程序的专业部署和开发.
---------⬆️
.
在部署Python程序的Web应用程序时,能够根据性能的需求,选择合适的wsgi server,不一样的wsgi server区别在于并发支持上,有单线程、多进程、多线程、协程的区别,其功能类似,无非是请求路由,执行对应的函数,返回处理结果.python
关于Django环境中的wsgi.py文件
上图是Django环境中的wsgi.py文件.
.
Django的主要部署平台是WSGI,其用于Web服务器和应用程序的Python标准.
.
Django的startproject管理命令设置一个简单的默认WSGI设置,能够根据需求为咱们的项目进行调整,并指示任何符合WSGI的应用程序服务器使用.
.
application使用WSGI部署的关键概念是应用程序服务器用于与代码通讯的application可调用,它一般在服务器可访问的Python模块中做为名为application的对象提供.
.
startproject命令建立包含这样的application可调用的文件:
<project_name>/wsgi.py,它被Django的开发服务器和生产WSGI部署使用,WSGI服务器从其配置中获取application可调用的路径。Django的内置服务器,即runserver命令,从WSGI_APPLICATION设置读取它.nginx
为何使用Nginx,uWSGI
.
首先,nginx是对外的服务接口,外部浏览器经过url访问nginx.
.
而后,nginx接收到浏览器发送过来的http请求,将包进行解析并分析url。若是是静态文件请求就访问用户给nginx配置的静态文件目录,直接返回用户请求的静态文件,若是不是静态文件请求(即动态请求),那么nginx就将请求转发给uwsgi,uwsgi接收到请求以后将包进行处理,处理成wsgi能够接收的格式,并发给wsgi。wsgi根据请求调用应用程序中的某个文件,或者某个文件中的某个函数,最后处理完将返回值再次交给wsgi,wsgi将返回值进行打包,打包成uwsgi可以接收的格式,uwsgi接收wsgi发送的请求,并转发给nginx,nginx最终将返回值返回给浏览器.
.
最后,要知道第一级的nginx并非必须的,uwsgi彻底能够完成整个的和浏览器交互的流程,可是要考虑到下面3种状况.
.
1.安全问题
程序不能直接被浏览器访问到,而是经过nginx,nginx只开发某个接口.
uwsgi自己是内网接口,这样运维人员在nginx中加上安全性的限制,能够达到保护程序的做为.
.
2.负载均衡问题
一个uwsgi极可能不够用,即便开多个work也是不行,毕竟一台机器的cpu和内存是有限的.
而使用nginx作代理,一个nginx能够代理多台uwsgi完成uwsgi的负载均衡.
.
3.静态文件问题
用Django或是uwsgi来负责静态文件的处理是很浪费的行为,它们自己对文件的处理也不如nginx,因此整个静态文件的处理都直接由nginx完成,静态文件的访问彻底不去通过uwsgi以及其后面的逻辑.程序员
下面将对Nginx、WSGI、uwsgi、uWSGI、Django之间的关系进行梳理.
.
---------⬇️
wsgi
全称web server gateway interface,wsgi不是服务器,也不是Python模块,而是一种通讯协议.
其用于描述web server如何与web application进行通信.
运行在wsgi上的web框架有Bottle、Flask、Django.
.
uwsgi
与wsgi同样,是通讯协议,是uWSGI服务器的单独协议,用于定义传输信息的类型.
.
uWSGI
是一个web服务器,实现了WSGI协议,uwsgi协议.
.
Nginx
web服务器,更加安全,更好的处理静态资源,缓存功能,负载均衡.
nginx的强劲性能,配合我WSGI服务器会更加安全,性能有保障.
.
Django
高级的Python框架,用于快速开发,解决web开发的大部分麻烦,程序员能够更加专一于业务逻辑,无序从新造轮子.
---------⬆️
.
逻辑图:
---------⬇️
web服务器
传统的C/S架构,请求的过程是:
客户端 > 服务器
服务器 > 客户端
服务器就是:1.接收请求 2.处理请求 3.返回响应
.
web框架层
HTTP的动态数据交给web框架,例如Django遵循MTV模式处理请求.
HTTP协议使用url定位资源,urls.py将路由请求交给views视图处理,而后返回一个结果,完成一次请求.
web框架使用者只须要处理业务的逻辑便可.
---------⬆️
.
若是将一次通讯转化为“对话”的过程:
Nginx:“Hello WSGI,我刚收到了一个请求,你准备下,而后让Django来处理吧。”
WSGI:“好的,Nginx,我立刻设置环境变量,而后把请求交给Django。”
Django:“谢谢 WSGI,我处理完请求立刻给你响应结果。”
WSGI:“好的,我在等。”
Django:“搞定啦,麻烦WSGI把响应结果传递给Nginx。”
WSGI:“Very good Nginx,响应结果请收好,已经按照要求传递给你了。”
Nginx:“好的,我这就把响应结果交给客户,合做愉快。”web
安装uWSGIapache
# 进入虚拟环境,安装uWSGI (venv) [root@master ~]# pip3.6 install uwsgi # 检查uWSGI版本 (venv) [root@master ~]# uwsgi --version 2.0.17.1 # 检查uWSGI Python版本 (venv) [root@master ~]# uwsgi --python-version 3.6.7
运行简单的uWSGIdjango
test.py文件以下:浏览器
def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'Hello World'] # Python3
运行命令以下:缓存
uwsgi --http :8000 --wsgi-file test.py """参数详解: --http :8000 -> 使用http协议,端口8000 --wsgi-file test.py -> 加载test.py文件 """
运行后,可从浏览器访问:tomcat
uWSGI运行Django环境
.
----------------------------------
经过命令运行Django环境# 在项目根目录下执行以下命令 uwsgi --http :8000 --module project.wsgi """参数详解: --http :8000 -> 使用http协议,端口8000 ----module -> 加载project项目下的wsgi模块 """.
----------------------------------
使用脚本运行Django环境
.
uWSGI支持ini、xml等多种配置方式.
这里将以ini为例,在/etc/目录下新建uwsgi_nginx.ini配置文件,以下:# 项目配置文件 [uwsgi] # 项目的绝对路径 定位到第一层 chdir = /root/oldboy # 指定项目的wsgi文件路径(从项目的根路径开始) module = oldboy.wsgi # 指定虚拟解释器的第一层路径 home = /root/Envs/oldboy # 指定经过uwsgi启动多少个进程 processes = 4 # 若是你已经配置了nginx,请使用这个socket链接 socket = 0.0.0.0:9999 # 若是你没有配置nginx,想经过uwsgi直接启动web服务,请使用这个http链接,指明http协议 # http = 0.0.0.0:9999 # 用于在退出uwsgi环境后清空环境变量 vacuum = true指定配置文件启动命令:
uwsgi --ini /etc/uwsgi_nginx.ini
uWSGI热加载Python程序
.
在启动命令的后面加上--py-autoreload=1便可# 命令启动 uwsgi --http :8000 --module mysite.wsgi --py-autoreload=1 # 配置文件启动 uwsgi --ini uwsgi.ini --py-autoreload=1此时修改Django代码,uWSGI会自动加载Django程序,页面生效.
这里咱们只讲解Nginx配置文件部分
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; keepalive_timeout 65; # 负载集群 upstream load { server 192.168.1.100:9999; server 192.168.1.200:9999; server 192.168.1.300:9999; } server { listen 80; server_name 192.168.43.149; location / { # nginx自带的ngx_http_uwsgi_module模块,起到nginx和uwsgi交互的做用 # 经过uwsgi_pass指定服务器地址和协议,将动态请求转发给uwsgi处理 uwsgi_pass load; include /usr/local/nginx1.12/conf/uwsgi_params; } # nginx处理静态页面资源 location /static { alias /data/static/; } # nginx处理媒体资源 location /media { alias/data/media/; } } }
配置完后重启Nginx,便可实现其功能.
supervisor是基于Python的任务管理工具,用于自动运行各类后台任务。固然咱们也能直接使用Linux的nohup命令是任务自动后台运行,但若是要重启任务,就得手动去kill掉任务进程。这样很繁琐,并且一旦程序错误致使进程退出的话,系统也没法自动重载任务。
下载
# 因为supervisor在python3下没法使用,所以只能用python2去下载 yum install python-setuptools easy_install supervisor
经过下面的命令生成supervisor的配置文件
echo_supervisord_conf > /etc/supervisord.conf
而后在/etc/supervisord.conf末尾添加以下代码
[program:django_test] # [program:项目名称] command=/root/Envs/djang1.11.11/bin/uwsgi --ini /root/django_test/uwsgi.ini # 程序启动命令 autostart=true # 在supervisord启动的时候也自动启动,可以使uWSGI程序被杀掉后自动运行 # 这里咱们只使用到了上面两个参数⬆️ # startsecs=10 # 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒 # autorestart=true # 程序退出后自动重启,可选值有:[unexpected,true,false],默认为unexpected,表示进程被意外杀死后才重启 # startretries=3 # 启动失败自动重试次数,默认是3 # user=django1.11.11 # 用哪一个用户启动进程,默认为root # priority=999 # 进程启动优先级,默认999,值小的优先启动 # redirect_stderr=true # 把stderr重定向到stdout,默认false # stdout_logfile_maxbytes=20MB # stdout 日志文件大小,默认50MB # stdout_logfile_backups = 20 # stdout 日志文件备份数,默认是10 # stdout # 日志文件,须要注意当指定目录不存在时没法正常启动,因此须要手动建立目录(supervisord 会自动建立日志文件) # stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out # stopasgroup=false # 默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程 # killasgroup=false # 默认为false,向进程组发送kill信号,包括子进程
其中command是结合virtualenv的命令和supervisor的精髓:
command=/root/Envs/djang1.11.11/bin/uwsgi --ini /root/django_test/uwsgi.ini command=/root/Envs/djang1.11.11/bin/uwsgi --uwsgi 0.0.0.0:8000 --chdir /root/django_test --home=/root/venv --module django_test.wsgi # --chdir:指定项目的根 # --home:指的是虚拟环境目录 # --module:找到Django项目环境中的wsgi.py文件
启动supervisor
# 启动supervisor supervisord -c /etc/supervisord.conf # 重启my项目 supervisorctl -c /etc/supervisord.conf restart my supervisorctl -c /etc/supervisord.conf [start|stop|restart] [program-name|all]
从新加载supervisor
supervisorctl update # 更新新的配置到supervisord supervisorctl reload # 从新启动配置中的全部程序 supervisorctl start program_name # 启动某个进程(program_name=你配置中写的程序名称) supervisorctl # 查看正在守候的进程 pervisorctl stop program_name # 中止某一进程 (program_name=你配置中写的程序名称) supervisorctl restart program_name # 重启某一进程 (program_name=你配置中写的程序名称) supervisorctl stop all # 中止所有进程 # 注意:显示用stop中止掉的进程,用reload或者update都不会自动重启。
mysite/settings.py
# 此参数会将将全部STATICFILES_DIRS中全部文件夹中的文件,以及各app中static中的文件都复制到指定的路径下 STATIC_ROOT='/data/static' STATIC_URL='/static' STATICFILES_DIRS=[ os.path.join(BASE_DIR, 'static'), ]
配置完毕后,运行命令:
python3.6 manage.py collectstatic
上面的命令会收集全部咱们项目中全部的静态文件并保存到STATIC_ROOT指定的路径下.把这些文件放到一块儿是为了用nginx等部署的时候更方便.