django + uwsgi + nginx部署(前后端不分离)
一、基础
-
uWSGI
一个基于自有的uwsgi协议、wsgi协议和http服务协议的web网关 -
nginx
常用高性能代理服务器 -
wsgi.py
django项目携带的一个wsgi接口文件
如果项目名叫destiny的话,此文件就位于[destiny/destiny/wsgi.py],即settings.py
相同目录下 -
wsgi:一种实现python解析的通用接口标准/协议,是一种通用的接口标准或者接口协议,实现了python web程序与服务器之间交互的通用性。
利用它,web.py或bottle或者django等等的python web开发框架,就可以轻松地部署在不同的web server上了; -
uwsgi:同WSGI一样是一种通信协议
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,它与WSGI相比是两样东西。 -
uWSGI :一种python web server或称为Server/Gateway
uWSGI类似tornado web或者flup,是一种python web server,uWSGI是实现了uwsgi和WSGI两种协议的Web服务器,负责响应python 的web请求。
因为apache、nginx等,它们自己都没有解析动态语言如php的功能,而是分派给其他模块来做,比如apache就可以说内置了php模块,让人感觉好像apache就支持php一样。 -
uWSGI实现了wsgi协议、uwsgi协议、http等协议。 Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
二、生产环境下请求流程
- 用户浏览器利用
HTTP协议
向nginx服务其发请求 - nginx接收到用户的请求,进行处理
- 如果是静态文件请求,nginx直接返回静态文件
- 如果是动态请求,nginx使用
socket
将请求转发给uWSGI服务器,uWSGI利用wsgi协议
将请求转发给正真的应用程序进行处理,结果反方向一次返回给浏览器
三、开发环境与生产环境区别
例如:Django
-
开发环境,即 DEBUG=True
-
使用
python manage.py runserver 127.0.0.1:8000
启动web,在浏览器中即可通过127.0.0.1:8000
进行访问-
此时的web服务器使用的是 django框架中内置的
runserver
服务器 -
开发模式下,访问静态文件,只需在url中配置,
runserver
会自动对静态文件进行处理,只在开发环境下生效,在生产环境下不会生效from django.conf.urls.static import static urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT) # 或者 from django.views.static import serve urlpatterns.append(url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'}))
-
-
-
生产环境,即 DEBUG=False
-
此时,不会在使用django内置的web服务器,需要手动指定,一般python使用
uWSGI服务器
-
但是
uWSGI
对静态的文件请求不能处理,此时需要使用nginx
进行请求的分发,分为静态请求与动态请求 -
如果是静态文件请求就根据nginx配置的静态文件目录,返回请求的资源;
如果是动态的请求,nginx就通过配置文件,将请求传递给uWSGI
;uWSGI
将接收到的包进行处理,并转发给wsgi
,wsgi
根据请求调用django工程的某个文件或函数,处理完后django将返回值交给wsgi
,
wsgi
将返回值进行打包,转发给uWSGI
,uWSGI
接收后转发给nginx
,nginx
最终将返回值返回给客户端(如浏览器
-
四、Nginx与uWSGI作用
- Nginx
- nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析
- nginx上加上安全性或其他的限制,可以达到保护程序的作用
- nginx来处理静态文件的效率很好
- uWSGI
- uWSGI是内网接口,开启多个work和processes可能也不够用,而nginx可以代理多台uWSGI完成uWSGI的负载均衡
- django在
debug=False
下,uWSGI 对静态文件的处理能力不是很好
五、安装与配置
-
uwsgi
-
pip3 install uwsgi
-
测试uWSGI
# 1.测试文件 test.py def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return (b"Hello World") # 2.运行 uwsgi --http 0.0.0.0:8000 --wsgi-file test.py # 3.验证 浏览器中打开 0.0.0.0:8000, 会返回 “Hello World”
-
如果端口被占用
# 列出占用端口的程序的pid号 lsof -i :8000 # kill占用端口程序 kill -9 <pid>
-
项目目录下建立
uwsgi.ini
socket:使用nginx时用socket,不适用nginx时用http
chdir:项目的目录
wsgi-file:项目下
wsgi.py
的路径,相对与chdir目录daemonize:uwsgi日志保存位置,相对于chdir目录或指定绝对路径
pidfile:记录当前运行的uwsgi进程id
[uwsgi] socket = 127.0.0.1:8888 chdir =/root/semf wsgi-file = SeMF/wsgi.py master =true process = 4 threads = 2 daemonize = logs/uwsgi.log pidfile = uwsgi.pid
-
-
Nginx
-
sudo apt-get install nginx
-
确定nginx默认配置文件路径
# 如果不知道哪里 nginx -t # 正常结果 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
-
检查默认配置目录下是否有
uwsgi_params
文件,必须确保存在此文件uwsgi_params
文件用于nginx
和uwsgi
之间的请求格式的转换uwsgi_params
文件中包含的内容如下:各个变量意义,参考文档:https://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/Vars.html
uwsgi_param QUERY_STRING $query_string; uwsgi_param REQUEST_METHOD $request_method; uwsgi_param CONTENT_TYPE $content_type; uwsgi_param CONTENT_LENGTH $content_length; uwsgi_param REQUEST_URI $request_uri; uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; uwsgi_param REMOTE_PORT $remote_port; uwsgi_param SERVER_PORT $server_port; uwsgi_param SERVER_NAME $server_name;
-
配置文件设置
备份复制原
/etc/nginx/nginx.conf
文件,在项目目录下新建nginx.conf
,粘贴默认配置文件中内容并新增一下内容(在http字典中)listen:nginx监听的端口
access_log:nginx访问日志保存路径
error_log:nginx错误日志保存路径
client_max_body_size:允许上传的文件最大大小
location /{}:处理动态请求
location /static{}:处理静态请求
location /upload:媒体资源,用户上传文件路径
uwsgi_pass:要和uwsgi.ini中的socket相同
server { listen 80; server_name localhost; charset utf-8; access_log /root/semf/logs/nginx_access.log; error_log /root/semf/logs/nginx_error.log; client_max_body_size 500m; location / { include /etc/nginx/uwsgi_params; uwsgi_pass 127.0.0.1:8888; } location /static { alias /root/semf/collectstatic/; } location /upload { alias /root/semf/media/; } }
-
六、启动
-
uwsgi启动
uwsgi --ini uwsgi.ini uwsgi --reload uwsgi.pid # 前提是在配置文件中配置了pid文件 uwsgi --stop uwsgi.pid # # 前提是在配置文件中配置了pid文件 # 或者 ps -aux | grep 'uwsgi' , 然后kill再启动
-
nginx启动
/etc/init.d/nginx start /etc/init.d/nginx stop /etc/init.d/nginx reload
七、验证
浏览器中ip:port