【Django 029】部署到Nginx之配合wsgi返回动态内容

上一节中我们已经能够成功在nginx返回本地静态资源,没有太多django有关的配置。但是动态资源必须要借助django中的MTV模型来完成了,这一节我们就来看看如何真正将django部署到nginx上。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

什么是wsgi

wsgi,全称Web Server Gateway Interface,是 PEP 3333中定义的一个python标准。这个标准描述了一个web服务器(例如nginx)如何和web应用(例如django)进行通讯的,同时也描述了多个web应用如何通过级联来对一个请求进行处理的。

1-chart.png

如上图所示,这里的uwsgi是对wsgi协议的一种实现,是一个单独组件,可和nginx部署在不同服务器,不过其必须和django安装在一台服务器上。uwsgi中可以配置django的信息,同时又可以暴露ip和端口给nginx来访问,从而完成一个中间件的目的。在接下来的操作中,我们分阶段来完成配置,首先确保uwsgi和django的连接正常,再确保nginx到uwsgi的连接正常。

django框架已经天然支持wsgi协议,如下图所示,新创建的项目目录中会自带一个wsgi.py文件。这个文件在稍后的操作中会作为django暴露给uwsgi的一个接口

2-django.png

nginx也天然对uwsgi支持,如果是按照上一节的方式安装的nginx,会发现在配置目录/etc/nginx/已经有了和uwsgi有关的配置文件。这个配置文件会在稍后的操作中用于转发请求到uwsgi

(therm) (base) [root@ai-therm nginx]# ll *wsgi*
-rw-r--r-- 1 root root 664 Oct  3  2019 uwsgi_params
-rw-r--r-- 1 root root 664 Oct  3  2019 uwsgi_params.default

uwsgi的安装和基本配置

首先要进行uwsgi的安装,直接pip安装即可

pip install uwsgi

我这里安装的是2.0.18版本

(therm) (base) [root@ai-therm therm]# pip freeze
Django==2.2.10
pytz==2020.1
sqlparse==0.3.1
uWSGI==2.0.18

如果出现类似you need a C compiler to build uWSGI的报错,需要安装一下gcc

yum -y install gcc

接下来在django的项目根目录新建uwsgi的配置文件uwsgi.ini,类似下面这样

[uwsgi]
#for nginx
#socket=0.0.0.0:9999
#for web server
http=0.0.0.0:9999
#working dir
chdir=/root/projects/therm/API
#wsgi.py file, relative to chdir
wsgi-file=API/wsgi.py

processes=2
threads=2
enable-threads=True
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log

首先有必要解释下websocket和http的区别。这两者都是不同的应用层协议,并且都基于tcp。区别就在于

  1. http是单向传输,而websocket是双向

  2. http是短连接,客户端发送请求之后会在收到服务器的返回后断掉连接。而websocket是长连接,该连接会一直保持直到心跳检测失败

  3. websocket经常用于频繁发起请求的场景,例如语音聊天,股票实时更新等,这种情况下使用http会对服务器造成很大负载

这里的几个字段说明如下

  • socket - 采用websocket方式监听请求,因为nginx连接uwsgi采用socket方式,所以最后一定通过这个配置完成连接
  • http - 采用http方式监听请求,这个配置使得uwsgi可以直接做为web服务器处理http请求,方便用来检测uwsgi和django的连接
  • chdir - 整个配置的根目录,配置为django项目的根目录即可
  • wsgi-file - 就是前面提到的django项目初始化的时候自带的wsgi.py文件的地址,相对于上面chdir的路径
  • master - 采用类似nginx的master+worker的方式启动
  • pidfile/daemonize - 记录pid和日志的文件路径,也是相对于上面chdir的相对路径,直接和配置文件一起放在django项目根目录即可

因为我们接下来要进行uwsgi和django的对接,所以这里将uwsgi配置为http模式,监听在所有网卡的9999端口。

uwsgi对接django

创建一个应用test用作测试,先在主目录中包含该应用的路由

path('test/', include('Test.urls')),

然后在test应用中新建路由入下

path('hello/', views.hello),

以及view函数

def hello(request):
    return JsonResponse(data={'status': 'Success', 'message': 'hello from xiaofu'})

先验证下django的配置没问题,采用自带的runserver来验证下

python manage.py runserver
(therm) (base) [root@ai-therm API]# curl 127.0.0.1:8000/test/hello/
{"status": "Success", "message": "hello from xiaofu"}

然后采用如下方式启动uwsgi,建议使用绝对路径

(therm) (base) [root@ai-therm API]# uwsgi --ini /root/projects/therm/API/uwsgi.ini 
[uWSGI] getting INI configuration from /root/projects/therm/API/uwsgi.ini

之后就能看到master+worker的方式启动了uwsgi

(therm) (base) [root@ai-therm API]# ps -ef | grep wsgi
root     31446     1  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31447 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31448 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31449 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31453 31120  0 21:18 pts/1    00:00:00 grep --color=auto wsgi

尝试通过外网的9999端口访问看看

3-http.png

这样就说明uwsgi到django的连接是没问题的,一会儿只需要将http改为socket即可。

nginx对接uwsgi

首先将uwsgi的配置从http改为socket

[uwsgi]
#for nginx
socket=0.0.0.0:9999
#for web server
#http=0.0.0.0:9999
#working dir
chdir=/root/projects/therm/API
#wsgi.py file, relative to chdir
wsgi-file=API/wsgi.py

processes=2
threads=2
enable-threads=True
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log

停掉进程

(therm) (base) [root@ai-therm API]# ps -ef | grep uwsgi
root     31446     1  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31447 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31448 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31449 31446  0 21:17 ?        00:00:00 uwsgi --ini /root/projects/therm/API/uwsgi.ini
root     31462 31120  0 21:22 pts/1    00:00:00 grep --color=auto uwsgi
(therm) (base) [root@ai-therm API]# kill -9 31446
(therm) (base) [root@ai-therm API]# ps -ef | grep uwsgi
root     31464 31120  0 21:23 pts/1    00:00:00 grep --color=auto uwsgi

重新启动

(therm) (base) [root@ai-therm API]# uwsgi --ini /root/projects/therm/API/uwsgi.ini 
[uWSGI] getting INI configuration from /root/projects/therm/API/uwsgi.ini

之后再nginx配置中加入下面的location匹配规则

location / {
                include /etc/nginx/uwsgi_params;
                uwsgi_pass 127.0.0.1:9999;
            }

我这里因为nginx和uwsgi在同一台机器上所以采用127.0.0.1,如果是分布式部署,需要采用外网ip。

重新载入配置

(therm) (base) [root@ai-therm API]# nginx -s reload

采用访问nginx机器的80端口看看

4-socket.png

这样就成功从nginx返回了django的结果。以后修改了django项目的内容,记住重启uwsgi来生效。

总结

只需要分三步进行配置

  • 首先确保django的runserver能正常访问
  • 然后确保uwsgi能成功连接到django,也就是uwsgi的配置没问题
  • 最后确保nginx能成功连接到uwsgi,也就是nginx的配置没问题

逐步确认,最后完成整体配置。

到了这里,django项目部署到nginx就算基本完成了。但是随着网络安全得到越来越重视,我们最好是将http请求都改为https请求,而这在nginx配置也非常容易,下一节我们一起来看看。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值