Django生产环境部署——Nginx和uwsgi详解(四)-创新互联
WSGI(the Python Web Server Gateway Interface)指Python的Web服务的网关接口。从名称上看,WSGI是一个网关,网关的作用是在协议之间进行转换。因此,WSGI是一个Web服务器与Django等程序进行通信的规范或者协议。WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。简单来说,WSGI就是一种协议规范,起到规范参数的作用,类似于高速公路上的限速一样,规定你此路段不能超过100km/h,同时一条高速公路有两个地点,如京沪高速,北京跟上海各占一端,那么他们之间的行车规范就按照WSGI规则进行。即WSGI沟通的双方是wsgi server(uWSGI)和 wsgi application(django)。
wsgi server (uWSGI)实现wsgi协议规范的服务器叫做wsgi服务器,也就是uWSGI服务器。
wsgi application (Django) 用以实现wsgi协议的应用,叫做wsgi应用,如Django,Falsk等。
uWSGI是一个快速的、纯C语言开发的、自维护的等WSGI服务器,旨在实现专业的Python Web应用开发和发布,它实现了WSGI、uwsgi、HTTP等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
uWSGI是一个web服务器,或者是是wsgi server 服务器。其作用就是接收用户请求,用户请求是通过网络使用http协议发来的,因此服务器要想正确解析http协议就需要uWSGI实现解析 。当uWSGI解析成功后就需要把解析出来的信息发给Django,此时就需要WSGI协议了。uWSGI实现了WSGI协议,所以uWSGI将用户请求的信息做一下简单的封装处理通过WSGI协议发送给后端的Django,Django接受的请求后先通过一层层中间件,并根据其请求的url发送给不同的视图函数(View),视图函数通过处理在依次返回Django,Django通过WSGI协议返回给uWSGI服务器。uWSGI服务器最后返回给请求的用户。受Django自带的web服务器性能原因(单进程单线程,处理请求慢等),因此在开发过程中,使用uWSGI来代替Django自带的服务器。
上面的这个流程似乎并没有涉及uwsgi,不急,慢慢看下文:
uWSGI虽然也能处理静态资源,但能力远不如高效的Nginx,并且生产环境下需要为集群实现负载均衡的功能,那么就会使用Nginx作为上游服务器用做处理静态资源以实现负载均衡。而使用nginx的proxy_pass功能向uWSGI转发http包,因他们之间使用的是http协议,所以需要用--http-socket
模式启动,nginx就能向uWSGI发送请求了。但是使用proxy_pass代理发送请求给uWSGI的架构,有个缺点,即http协议解析了两次,nginx和uWSGI各自解析了一次,因此效率会慢点。因此uWSGI就开发出了uwsgi协议,该协议解析比http解析快,如果上游服务(Nginx)能够兼容uwsgi协议,那么上游Nginx与uWSGI之间就能通过uwsgi进行沟通并传输数据,该情况下,http只在上游解析了一次,效率更高。因此uwsgi应运而生。常用的Nginx、Apache都兼容uwsgi协议,若使用uwsgi协议,则需要用--http-socket
,上游服务器Nginx使用uwsgi_pass
代替proxy_pass
uwsgi是一个具体的线路协议,用来实现uWSGI服务器与其他服务软件(例如:Nginx)的数据通信。uwsgi官方文档
整体流程如下:
在django带有manange.py的同一级目录下常见一个uwsgi.ini文件,文件内容如下:
[uwsgi]
# 指定项目的路径,及带有manage.py的上一级目录
chdir = /home/user/maproject/backma
# wsgi文件路径,即带有wsgi.py 的文件
module = config.wsgi
# the virtualenv path 虚拟环境安装目录,我的虚拟环境名为django,不知道可以使用which django查看一下,直接复制粘贴过来。
virtualenv = /root/.virtualenvs/django
# 是否开启master进程,启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。
master= true
# process-related settings
master = /home/user/maproject/logs/uwsgi88.pid
# 工作进程的大数目,指定uwsgi启动的进程数
processes = 4
#启动2两个线程数
threads = 2
# 使用nginx时使用socket参数,一定要跟nginx的配置的转发接口一致。
socket = 127.0.0.1:8080
# 当服务器退出时自动删除unix socket文件和pid文件,结束后是否清理文件
vacuum = true
# 后台启动,使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
daemonize = /home/user/maproject/logs/django_logs.log
#指定pid文件
pidfile = /var/run/uwsgi.pid
# 设置用于uwsgi包解析的内部缓存区大小为64k,默认是4k。
buffer-size = 65535
#为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏。
max-requests = 5000
#通过使用POSIX/UNIX的setrlimit()函数来限制每个uWSGI进程的虚拟内存使用数。这个配置会限制uWSGI的进程占用虚拟内存不超过256M。如果虚拟内存已经达到256M,并继续申请虚拟内存则会使程序报内存错误,本次的http请求将返回500错误。
limit-as = 256
#一个请求花费的时间超过了这个harakiri超时时间,那么这个请求都会被丢弃,并且当前处理这个请求的工作进程会被回收再利用(即重启)
harakiri = 60
在uwsgi.ini当前目录下启动uwsgi,启动命令如下:
uwsgi --ini uwsgi.ini
关闭uwsgi服务,命令如下:
pkill -f uwsgi -9
四、WSGI、uWSGI与uwsgi三者关系即归纳WSGI:网关、接口。
uwsgi:线路协议。
uWSGI:一种服务的具体实现。
为什么使用了uWSGI还需要使用Nginx?
前面说过,uWSGI虽然能处理静态资源,但远不能如Nginx处理的高效,并且考虑为集群实现负载均衡,所以,在一般的生产环境下,使用Nginx+uWSGI(或者Gunicorn)来对网站进行部署。
使用了uWSGI还使用Nginx的好处如下:
Nginx处理静态文件更有优势,性能更好。
Nginx更安全。
Nginx可以进行多台机器的负载均衡。
nginx是一个高性能的http和反向代理服务器,也是IMAP/POP3/SMTP代理服务器,其以事件驱动的方式编写。
在性能上,Nginx占用很少的系统资源,支持更多的并发连接,可达到更高的访问效率。
在功能上,Nginx是优秀的代理服务器和负载均衡服务器。
在安装配置上,Nginx安装简单、配置灵活。
Nginx支持热部署,启动速度快,可以在不间断的情况下对软件版本或配置进行升级,且运行数个月也无需重启。
简单说一下Nginx的正向代理和反向代理:
正向代理:
正向代理,代理的是客户端,用户的一切请求都交给代理服务器去完成,至于代理服务器如何完成,用户可以不用关心。其大的特点是客户端非常明确要访问的服务器地址,服务器只清楚来自哪个代理服务器,而不清楚来自哪个具体的客户端正向代理模式屏蔽或隐藏了真实客户端信息。
反向代理:
反向代理,代理的是服务器,隐藏了服务器的信息。如,当打开购物商城网站时,(现在网站都是分布式部署),浏览的某一页信息或者发送某个请求给反向代理服务器,该请求由反向代理具体分发到某一台服务器上去完成相关的请求处理,对用户而言,是感受不到反向代理的存在的。其大特点是:客户端是无感知代理的存在的,反向代理对外是透明的,访问者并不知道自己访问的是一个代理,因为客户端不需要配置就可以访问。反向代理,”它代理的是服务端,代理服务端接受请求“,且反向代理隐藏了服务器的信息。
#查看版本号
nginx -v
#启动nginx
service nginx start
#重启
service nginx restart
#重载
nginx -s reload
#停止nginx
nginx -s stop #直接停止
nginx -s quit #完成已经接收的连接请求后再退出
#查看nginx进程
ps -ef | grep nginx
Nginx文件保存位置:/usr/sbin/nginx:主程序
/etc/nginx:存放配置文件
/usr/share/nginx:存放静态文件
/var/log/nginx:存放日志
Nginx配置文件详解:利用vi 命令打开/etc/nginx/nginx.conf
nginx配置文件大致分为三部分:全局部分、event部分、http部分。
1. 全局部分:
#指定nginx运行的用户及用户组,默认为nobody,可以使用linux的user用户运行ngixn,不要使用root,有风险存在。
user nobody;
#开启的进程数,一般小于或等于CPU数
worker_processes 1;
#定位全局错误日志文件,级别以notice显示,还有debug,info,warn,error,crit模式,
#debug输出最多,crir输出最少,根据实际环境而定
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
#指定进程号的保存位置
pid logs/nginx.pid;
2. events部分:
events { #设置工作模式为epoll,除此之外还有select,poll,kqueue,rtsig和/dev/poll模式
use epoll;
#定义每个进程的大连接数,受系统进程的大打开文件数量限制,默认为1024.
worker_connections 1024;
}
3. http部分:
http部分包括的参数有文件引入、日志格式定义、连接数等,其中server块相当于一个站点、一个http块可以有多个server块。
2 http { #文件扩展名与文件类型的映射。主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度。
include mime.types;
#默认文件类型。核心模块指令,智力默认设置为二进制流,也就是当文件类型未定义时使用这种方式
default_type application/octet-stream;
#日志文件的输出格式,main为日志格式的名称,可自行设置,后面引用
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#引用日志main,
access_log logs/access.log main;
#设置允许客户端请求的大的单个文件字节数
#client_max_body_size 20M;
#指定来自客户端请求头的headebuffer大小
#client_header_buffer_size 32k;
#指定连接请求试图写入缓存文件的目录路径
#client_body_temp_path /dev/shm/client_body_temp;
#指定客户端请求中较大的消息头的缓存大数量和大小,目前设置为4个32KB
#large client_header_buffers 4 32k;
#设置客户端连接保存活动的超时时间
keepalive_timeout 65;
#开启高效文件传输模式
#sendfile on;
#开启防止网络阻塞
#tcp_nopush on;
#开启防止网络阻塞
#tcp_nodelay on;
#设置客户端请求读取超时时间
#client_header_timeout 10;
#设置客户端请求主体读取超时时间
#client_body_timeout 10;
#用于设置相应客户端的超时时间
#send_timeout
#server配置
server { #监听端口为 80
listen 80 default_server;
#设置主机域名或Ip
server_name 192.168.2.101;
#设置访问的语言编码
#charset koi8-r;
#设置虚拟主机访问日志的存放路径及日志的格式为main
#access_log logs/host.access.log main;
#设置虚拟主机的基本信息
location / { #设置虚拟主机的网站根目录,前端vue开发的静态资源
root /home/user/maproject/dist;
#设置虚拟主机默认访问的网页
index index.html index.htm;
# 主要参数
try_files $uri $uri/ /index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html { root html;
}
server { #前端访问后端的端口
listen 8000;
#监听前端的ip
server_name 192.168.2.101;
#设置django后端访问超管界面,转发给uWSGI处理
location ^~/admin/ { include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;
}
#访问后端的静态资源
location /static/ { #static文件夹所在的绝对路径
root /home/user/maproject/django_static; # 重定向,自动找到static
}
#访问后端的api请求,前段访问的后端api请求都以api开头
location /api { include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;
}
}
启动部署的项目时,先启动nginx,在启动uwsgi服务。
我的项目整体结构如下所示:
好了,基于Django开发的应用网站部署就到此结束了,从ubuntu server搭建到nginx与uwsgi的部署。鄙人也是初学者,在学习的路上一直在慢慢的积累,欢迎各位大佬的及时指正,如有纰漏,恳请及时纠正。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
当前标题:Django生产环境部署——Nginx和uwsgi详解(四)-创新互联
文章出自:http://myzitong.com/article/iceeo.html