一个Web服务器面对的是外部世界,它能直接从文件系统提供文件(HTML、图像等)。然而,它无法直接与Django应用通信,它需要借助一些工具的帮助来接收客户端的请求,然后返回响应。
理论篇(一):WSGI与uWSGI
- WSGI(wsgi)
全称Web Server Gateway Interface,或 Python Web Server Gateway Interface ,是为 Python 语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。
总结:WSGI(wsgi)只是一种规范,描述web server如何与web application通信的规范
- uWSGI
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。
- uwsgi
与WSGI一样是一种通信协议,但与WSGI协议是两种东西,uwsgi协议是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型的描述。
理论篇(二):Web请求流程
web请求流程如下所示:
the web client <-> the web server <-> the socket <-> uwsgi <-> Django
- 首先客户端请求服务资源
- nginx作为直接对外的的服务接口,接收到客户端发送过来的请求会解包、分析
- 如果是静态文件请求,根据配置直接返回请求的资源
- 如果是动态的请求,就通过配置文件传递给uWSGI
- uWSGI将接收到的包进行处理,并转发给wsgi,wsgi根据请求调用Django中的某个文件或函数,处理完后Django将返回值交给wsgi,wsgi将返回值进行打包,转发给uWSGI,uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端
理论篇(三):nginx的作用:
- 第一级的nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程;
- 在nginx上加上安全性或其他的限制,可以达到保护程序的作用;
- uWSGI本身是内网接口,开启多个work和processes可能也不够用,而nginx可以代理多台uWSGI完成uWSGI的负载均衡;
- django在debug=False下对静态文件的处理能力不是很好,而用nginx来处理更加高效。
实践篇(一):基础实验环境介绍
- 操作系统:CentOS
- Python:Python3
- Tools Version:
- nginx/1.14.
- uwsgi: 2.0.19.1
- nginx配置目录:/etc/nginx
- nginx配置文件:/etc/nginx/nginx.conf
实践篇(二):uWSGI安装与配置
1. uwsgi安装
sudo yum install python3-devel
pip3 install uwsgi
测试方式:使用uWSGI在8000端口运行Django项目
uwsgi --http 127.0.0.1:8000 --chdir /path/to/project/ --wsgi-file /path/to/wsgi.py
2. 配置项
chdirchdirchdir
基本选项:
-processes-threads-stats
--stats
telnetcurl
示例:
uwsgi --http 127.0.0.1:8000 --chdir /path/to/project/ --wsgi-file /path/to/wsgi.py --processes 4 --threads 2 --stats 127.0.0.1:8080
8000127.0.0.1:8080
3. 将配置项写入文件
可以把配置写在配置文件里,执行时只需要一个配置文件做参数:
# conf.ini
[uwsgi]
http = 127.0.0.1:8000
chdir = /path/to/project/
wsgi-file = /path/to/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:8080
考虑到安全性,uWSGI 文档中提到,不要使用 root 权限来运行 uWSGI,添加 uid 和 gid 选项指定用户和组。
使用配置文件运行:
uwsgi conf.ini
8000
实践篇(三):Nginx
1. 使用Nginx做基础代理转发
下面只给出最简单的配置示例:
server{
listen 80;
# 如果有域名
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
include uwsgi_params;
}
}
2. 使用Nginx做SSL代理转发
- 443端口代理
server {
#SSL 访问端口号为 443
listen 443 ssl;
#填写绑定证书的域名
server_name cloud.tencent.com;
#证书文件名称
ssl_certificate 1_cloud.tencent.com_bundle.crt;
#私钥文件名称
ssl_certificate_key 2_cloud.tencent.com.key;
ssl_session_timeout 5m;
#请按照以下协议配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
#网站主页路径。此路径仅供参考,具体请您按照实际目录操作。
root html;
index index.html index.htm;
}
}
- 其它自定义端口示例
server {
# 自定义端口
listen 2020 ssl;
# 域名
server_name www.example.com;
client_max_body_size 10M;
ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10s;
# 证书存放地址
ssl_certificate /etc/nginx/conf.d/ssl/adminSSl.pem;
ssl_certificate_key /etc/nginx/conf.d/ssl/adminSSl.key;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers HIGH:!aNULL:!MD5;
# error_page 497 301 https://$http_host$request_uri;
access_log /logs/admin.log;
index index.html;
root /html/peixun/dist;
charset utf-8;
location / {
try_files $uri $uri/ @router;
index index.html index.htm;
}
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 9;
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
error_page 405 =200 @405;
location @405{
root /opt/htdocs;
}
location @router {
rewrite ^.*$ /index.html last;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
expires 30d;
access_log on;
}
}