导读:很多朋友问到关于django为什么需要nginx的相关问题,本文首席CTO笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!
1. Django,Nginx 和 Gunicorn 的关系
在杜赛的博客中,对Django+Nginx+Gunicorn这三兄弟的描述是这样的:
如果用餐馆来做比喻的话,Nginx 就是迎宾小姐,客人如果点了酒水,迎宾小姐自己就帮忙拿了;而 Gunicorn 是传菜员,Django 是厨师,他两一起满足客人对现炒美食的需求。
这个比喻具体是在说什么呢?
首先,我们要分清楚 Web应用 和 Web服务器 这两个概念。Django开发出来的程序是Web应用,它本身不能起到监听用户请求并响应这种 “收发员” 的功能。监听用户请求并响应是 Web服务器 的职责。
Nginx就是一个 Web服务器 。即使没有web应用运行,只有一大堆 html 静态页面,我们也可以通过配置路由和返回的页面来使用Nginx搞出一个静态网站。
Django开发的Web应用本身是没有和客户端(浏览器)交互的功能的。我们在本地能够运行它是只是因为Django其内置了一个小型Web服务器而已,不过它性能受限,不能用于生产环境。
那么将Nginx和Django组合是不是就大功告吉了呢?没那么简单。Python官方定义了WSGI(Web Server Gateway Interface)作为Web服务器与Python Web应用程序或框架之间的建议标准接口。这样可以提高Web应用程序和服务器之间的可移植性。显然Django需要一个实现WSGI的服务器来和它配合。然而Nginx作为一个普通的http服务器,并没有实现这个接口。
这可以通过两种方式变通:
这里使用的是第二种途径。Gunicorn是一个遵循WSGI的Web服务器。Nginx可以在需要和Django打交道的时候把任务交给Gunicorn处理,而在不需要的时候自己解决就行。在我们的情况下就是 /static 和 /media 这种静态资源由 Nginx 自行快速响应,其他请求通过socket传送给Gunicorn,Gunicorn通过WSGI和Django通信并返回动态响应。这就是为什么说传菜员Gunicorn和厨师Django 他俩一起 满足顾客对现炒美食的需求。
其实Gunicorn本身不需要Nginx的带领也是可以独立运作的,但是它的性能比较差因此不推荐这么做。Gunicorn的 官方文档 也强烈推荐把Gunicorn部署在如Nginx这样的代理服务器的后方,以防止安全问题。
参考好文:
为什么nginx可以直接部署,还要uWSGI,gunicorn等中间件
名字是小明:尝试理解Flask源码 之 搞懂WSGI协议
如何用nginx关联django应用
通过Nginx部署Django(基于ubuntu)
Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式。
在这种方式中,我们的通常做法是,将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是NGINX的强项)。然后,NGINX将所有非静态请求通过uwsgi传递给Django,由Django来进行处理,从而完成一次WEB请求。
可见,uwsgi的作用就类似一个桥接器。起到桥梁的作用。
Linux的强项是用来做服务器,所以,下面的整个部署过程我们选择在Ubuntu下完成。
一、安装Nginx
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。
Nginx同样为当前非常流行的web服务器。利用其部署Django,我们在此也做简单的介绍。
Nginx官网:
打开ubuntu控制台(ctrl+alt+t)利用Ubuntu的仓库安装。
fnngj@ubuntu:~$ sudo apt-get install nginx #安装
启动Nginx:
fnngj@ubuntu:~$ /etc/init.d/nginx start #启动
fnngj@ubuntu:~$ /etc/init.d/nginx stop #关闭
fnngj@ubuntu:~$ /etc/init.d/nginx restart #重启
修改Nginx默认端口号,打开/etc/nginx/nginx.conf 文件,修改端口号。
复制代码
server {
listen 8088; # 修改端口号
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
复制代码
大概在文件36行的位置,将默认的80端口号改成其它端口号,如 8088。因为默认的80端口号很容易被其它应用程序占用。
然后,通过上面命令重启nginx。访问:http//127.0.0.1:8088/
如果出现如上图,说明Nginx启动成功。
二、安装uwsgi
通过pip安装uwsgi。
root@ubuntu:/etc# python3 -m pip install uwsgi
测试uwsgi,创建test.py文件:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
通过uwsgi运行该文件。
fnngj@ubuntu:~/pydj$ uwsgi --http :8001 --wsgi-file test.py
接下来配置Django与uwsgi连接。此处,假定的我的django项目位置为:/home/fnngj/pydj/myweb
fnngj@ubuntu:~/pydj$ uwsgi --http :8001 --chdir /home/fnngj/pydj/myweb/ --wsgi-file myweb/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191
常用选项:
http : 协议类型和端口号
processes : 开启的进程数量
workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number ofworkers / processes)
chdir : 指定运行目录(chdir to specified directory before apps loading)
wsgi-file : 载入wsgi-file(load .wsgi file)
stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)
threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)
master : 允许主进程存在(enable master process)
daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。
pidfile : 指定pid文件的位置,记录主进程的pid号。
vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)
三、Nginx+uwsgi+Django
接下来,我们要将三者结合起来。首先罗列一下项目的所需要的文件:
myweb/
├── manage.py
├── myweb/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── myweb_uwsgi.ini
在我们通过Django创建myweb项目时,在子目录myweb下已经帮我们生成的 wsgi.py文件。所以,我们只需要再创建myweb_uwsgi.ini配置文件即可,当然,uwsgi支持多种类型的配置文件,如xml,ini等。此处,使用ini类型的配置。
复制代码
# myweb_uwsgi.ini file
[uwsgi]
# Django-related settings
socket = :8000
# the base directory (full path)
chdir = /home/fnngj/pydj/myweb
# Django s wsgi file
module = myweb.wsgi
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 4
# ... with appropriate permissions - may be needed
# chmod-socket = 664
# clear environment on exit
vacuum = true
复制代码
这个配置,其实就相当于在上一小节中通过wsgi命令,后面跟一堆参数的方式,给文件化了。
socket 指定项目执行的端口号。
chdir 指定项目的目录。
module myweb.wsgi ,可以这么来理解,对于myweb_uwsgi.ini文件来说,与它的平级的有一个myweb目录,这个目录下有一个wsgi.py文件。
其它几个参数,可以参考上一小节中参数的介绍。
接下来,切换到myweb项目目录下,通过uwsgi命令读取myweb_uwsgi.ini文件启动项目。
复制代码
fnngj@ubuntu:~$ cd /home/fnngj/pydj/myweb/
fnngj@ubuntu:~/pydj/myweb$ uwsgi --ini myweb_uwsgi.ini
[uWSGI] getting INI configuration from myweb_uwsgi.ini
*** Starting uWSGI 2.0.12 (32bit) on [Sat Mar 12 13:05:06 2016] ***
compiled with version: 4.8.4 on 26 January 2016 06:14:41
os: Linux-3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015
nodename: ubuntu
machine: i686
clock source: unix
detected number of CPU cores: 2
current working directory: /home/fnngj/pydj/myweb
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /home/fnngj/pydj/myweb
your processes number limit is 15962
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address :8000 fd 3
Python version: 3.4.3 (default, Oct 14 2015, 20:37:06) [GCC 4.8.4]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x8b52dc0
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 319920 bytes (312 KB) for 4 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x8b52dc0 pid: 7158 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 7158)
spawned uWSGI worker 1 (pid: 7160, cores: 1)
spawned uWSGI worker 2 (pid: 7161, cores: 1)
spawned uWSGI worker 3 (pid: 7162, cores: 1)
spawned uWSGI worker 4 (pid: 7163, cores: 1)
复制代码
注意查看uwsgi的启动信息,如果有错,就要检查配置文件的参数是否设置有误。
再接下来要做的就是修改nginx.conf配置文件。打开/etc/nginx/nginx.conf文件,添加如下内容。
复制代码
……
server {
listen 8099;
server_name 127.0.0.1
charset UTF-8;
access_log /var/log/nginx/myweb_access.log;
error_log /var/log/nginx/myweb_error.log;
client_max_body_size 75M;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
uwsgi_read_timeout 2;
}
location /static {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias /home/fnngj/pydj/myweb/static/;
}
}
……
复制代码
listen 指定的是nginx代理uwsgi对外的端口号。
server_name 网上大多资料都是设置的一个网址(例,wwwexamplecom),我这里如果设置成网址无法访问,所以,指定的到了本机默认ip。
在进行配置的时候,我有个问题一直想不通。nginx到底是如何uwsgi产生关联。现在看来大概最主要的就是这两行配置。
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
include 必须指定为uwsgi_params;而uwsgi_pass指的本机IP的端口与myweb_uwsgi.ini配置文件中的必须一直。
现在重新启动nginx,翻看上面重启动nginx的命令。然后,访问:http//127.0.0.1:8099/
通过这个IP和端口号的指向,请求应该是先到nginx的。如果你在页面上执行一些请求,就会看到,这些请求最终会转到uwsgi来处理。
谁能帮帮我,Django部署问题,nginx和uWSGI
Django自己运行的只用于开发者调试,且为单线程工作。如果是要作为产品发布则需要用到其他的服务器部署,比较常见的用Nginx+uwsgi。
nginx和django的区别
nginx是Web服务器,用于正向和反向代理,负载均衡等。
Django是Web编程框架,帮助程序员,快速编写Web服务。
Django教程
如何用Nginx部署Django
如果你在windows上开发的django项目。部署的话,需要分三步。
第一步:在linux下下载python用的依赖包,搭建python环境。将windows下的项目复制到linux下,使用django自带服务进行启动。
第二步:下载uwsgi模块并且编写配置文件来替代django自带的服务模块。
第三步:下载nginx包,编译安装。然后创建配置文件,配置nginx启动django项目的信息。然后访问即可。
结语:以上就是首席CTO笔记为大家整理的关于django为什么需要nginx的相关内容解答汇总了,希望对您有所帮助!如果解决了您的问题欢迎分享给更多关注此问题的朋友喔~