nginx + uwsgi:高并发更稳定一些
nginx + gunicorn:更方便,性能可以从其它方面入手
一、概念
-
Nginx :
-
运行过程:
nginx作为服务器的最前端,它将接受WEB的所有请求,统一管理请求。 nginx把所有静态请求自己来处理 (这是nginx的强项,静态文件像我们django博客项目中的static文件夹下面的图片,css,js)。然后 nginx将所有的非静态请求 (像显示文章的详细信息,通常这类信息都保存在数据库,因此需要调用数据库获取数据) 通过uwsgi传递给Django,由django来处 理,从而完成一次WEB请求。uwsgi的作用就类似一个桥接器,起到桥梁的作用。
![](https://img-blog.csdnimg.cn/20200915145134679.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlaXd1aGVuOTI=,size_16,color_FFFFFF,t_70)
二、部署环境
需要安装p
ython3 nginx uwsgi django markdown
安装uwsgi:pip3 install uwsgi
安装django:pip3 install django
安装markdown:pip3 install markdown
测试uwsgi:
创建test.py文件:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
函数名application,这是默认的函数,uwsgi的python加载器会搜索这个名字把它部署到http端口8000
运行uwsgi:uwsgi --http :8000 --wsgi-file test.py,结果如下:
![](https://img-blog.csdnimg.cn/20200915145134680.png)
三、nginx+uwsgi+django配置
3.1、从github上clone你的Django项目
从Git上拉取mysite项目的时候,在子目录mysite下自动帮我们生成wsgi.py文件,我们只需要手动创建myweb_uwsgi.ini配置文件
![](https://img-blog.csdnimg.cn/20200915145134868.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlaXd1aGVuOTI=,size_16,color_FFFFFF,t_70)
3.2、配置myweb_uwsgi.ini文件
[root@SyslogVM mysite]# cat myweb_uwsgi.ini
[uwsgi]
# Django-related settings 用于和 nginx 进行数据交互的端口
socket = 127.0.0.1:8000 # 指定项目执行的端口,应用服务IP端口
# 对外提供 http 服务的端口
# http = IP:Port # web服务IP端口,uWSGI做web服务器时用
# python虚拟环境目录绝对路径。如果有的话,home是虚拟环境根目录,PYTHNONHOME是虚拟环境下的bin目录(放置了Python执行文件)
# home = /env
# PYTHONHOME = /env/bin
# the base directory (full path)
chdir = /home/Django_test/mysite # 指定项目的根目录
# Django s wsgi file
module = mysite.wsgi # 与myweb_uwsgi.ini文件平级有个mysite目录,该目录下有wsgi.py文件
# process-related settings
# master
master = true # 允许主线程存在(true)
# maximum number of worker processes
processes = 1 # processes:开启的进程数量与线程数量
threads = 2
# ... with appropriate permissions - may be needed
chmod-socket = 664
# clear environment on exit
vacuum = true # 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件
post-buffering=4096 # 设置缓冲
# 设置每个工作进程处理请求的上限,达到上限时,将回收(重启)进程,可以预防内存泄漏
max-requests=5000
# stats = %(chdir)/uwsgi/uwsgi.status
# pidfile = %(chdir)/uwsgi/uwsgi.pid # 保存主进程的pid,用来控制uwsgi服务。 uwsgi --stop/reload xxx.pid 停止/重启uwsgi
# daemonize = %(chdir)/uwsgi/uwsgi.log # 设置后台运行保存日志。只要配置了daemonize就会让uwsgi后台运行,同时将日志输出到指定目录
# disable-logging = true # 不记录正常信息,只记录错误信息
# 静态文件映射
# static-map = /static=Django下static目录的绝对路径
3.2、配置nginx
upstream django { # 负载均衡
server 127.0.0.1:8000;
}
server {
listen 8099; # 指定的是nginx代理uwsgi对外的端口号
server_name 127.0.0.1 # 服务器名字或者域名
charset UTF-8; # 字符集
client_max_body_size 75M;
access_log /home/Django_test/mysite/logs/myweb_access.log;
error_log /home/Django_test/mysite/logs/myweb_error.log;
# 指定项目路径uwsgi
location / {
include /etc/nginx/uwsgi_params; # 一般来说,你只需包含uwsgi_params文件,可以使用nginx里自带的
uwsgi_pass django; # 使用uwsgi_pass指令来设置uWSGI socket的地址,设置uwsgi服务器的协议和地址、端口
uwsgi_read_timeout 65; # 视图函数处理超时,uwsgi会关闭连接,这个关闭只是针对Nginx这边的关闭,视图函数还会继续执行,处理完成后,视图函数那边会报IO写入。
uwsgi_send_timeout 65;
uwsgi_connect_timeout 65;
}
location /static {
expires 30d; # 意味着静态和媒体文件夹中的所有内容将在30天内由浏览器缓存,但不会删除任何内容,您将无需重新生成服务器中的任何内容
autoindex on; # 启用目录流量, 默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间
add_header Cache-Control private; # HTTP协议的Cache -Control指定请求和响应遵循的缓存机制。private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器。
alias /home/Django_test/mysite/static; # 静态文件存放位置
}
}
3.4、启动nginx与uwsgi
http://10.21.144.111:8099/account/login成功访问web界
service nginx restart或者/etc/init.d/nginx start
uwsgi --ini myweb_uwsgi.ini # 启动
uwsgi --stop uwsgi.pid # 停止
uwsgi --restart uwsgi.pid # 重启
uwsgi --reload
四、problem
问题1:Invalid HTTP_HOST header: 'ip:8000'. You may need to add 'ip' to ALLOWED_HOSTS.
解决:修改setting.py,将 ALLOWED_HOSTS = [] 改为 ALLOWED_HOSTS = ['*']
问题2:
invalid request block size: 21573 (max 4096)...skip
原因:
我是使用nginx来把请求发送给uwsgi。所以uwsgi被配置成使用socket方式(为tcp协议)进行通信。
如果打开浏览器访问uwsgi指定的端口(这里是8000),那么浏览器请求uwsgi的方式为http协议,而不是socket方式。
所以就导致uwsgi的log文件中打出上面的错误信息。而我最初在myweb_uwsgi.ini配置的是socket= :8000,需要将其改成http = :8000。
如果打开浏览器访问uwsgi指定的端口(这里是8000),那么浏览器请求uwsgi的方式为http协议,而不是socket方式。
所以就导致uwsgi的log文件中打出上面的错误信息。而我最初在myweb_uwsgi.ini配置的是socket= :8000,需要将其改成http = :8000。
http://10.21.144.111:8099/account/login: socket= :8000
http://10.21.144.111:8000/account/login:http = :8000
五、参考:
https://www.cnblogs.com/chenice/p/6921727.html Django + Uwsgi + Nginx 的生产环境部署
https://www.cnblogs.com/fnng/p/5268633.html 通过Nginx部署Django(基于ubuntu)