Django框架的服务器架构一般是 Nginx + uWSGI + Django
网关协议CGI FCGI SCGI WSGI
- CGI = Common Gateway Interface
顾名思义,它是一种接口规范
。规范详细定义了Web服务器中运行的服务器代理程序,怎样获取及返回网页生成过程中,服务器环境上下文和HTTP协议中的参数名称,如大家所熟知的:REQUEST_METHOD,QUERY_STRING,CONTENT_TYPE等等。绝大部分的Web服务器程序,是以脚本的形式代理接受并处理HTTP请求,返回HTTP页面或响应。这些脚本程序,就是大家所熟知的PHP、ASP、JSP等等。
- FCGI = Fast CGI
它其实是CGI在具体实现中的的一个变种
。其设计思路是,通过减少CGI代理程序和Web宿主服务程序的通信开销,从而达到提高Web服务性能的最终目的。由此可见,FCGI在规范上跟CGI并没有不同,只是具体实现方式上有所改进:CGI的做法是,对于每个HTTP请求,Web宿主服务程序都建立新的进程以调用服务器脚本,相应该请求;FCGI的做法是,建立一个独立的FCGI服务程序进程,和Web宿主服务程序进程通信,FCGI服务进程被一旦启动后,自己分配资源、创建线程响应HTTP请求、并决定自身生命周期,从而大大降低了系统为了创建进程而做出的资源开销。现代流行的Web服务器程序,如PHP、ASP.Net,基本都是FCGI的实现。
- SCGI = Simple CGI
它是FCGI在精简数据协议和响应过程后的产物
。其设计目的是为了适应越来越多基于AJAX或REST的HTTP请求,而做出更快更简洁的应答。并且SCGI约定,当服务器返回对一个HTTP协议请求响应后,立刻关闭该HTTP连接。所以不难看出,SCGI更加适合于普遍意义上SOA所提倡的“请求-忘记”这种通信模式。
- WSGI = Web Server Gateway Interface
此协议是Python语言的专利
,它定义了一组在Web服务宿主程序和HTTP响应代理程序之间通信的普遍适用的接口。它的产生是因为Python程序员注意到,对于Web框架和Web宿主服务器程序间,有严重的耦合性,比如说,某些框架是针对Apache的mod_python设计的。于是,WSGI就定义了一套非常低级别的接口。常见的Python Web框架都实现了这个协议:如 CherryPy, Django, web.py, web2py, TurboGears, Tornado, Pylons, BlueBream, Google App Engine[dubious – discuss], Trac, Flask, Pyramid,等等.
WSGI协议,uwsgi协议
WSGI协议(通讯协议):Python用于Web开发的协议(用于处理Web服务器和应用程序(APP)的交互信息)
(把http通讯的过程抽象出来(请求数据,响应数据的封装),开发者只负责处理中途的数据)
uwsgi协议(传输协议,速度很快):uWSGI程序实现的一个自有的协议(采用二进制来存储数据,之前的协议都是使用字符串,所以在存储空间和解析速度上,都更快)
注意:
WSGI是一种通信协议。
uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
Web框架一般都自带wsgi服务器 但是性能不好,只作测试用途。(django–wsgiref)
wsgiref模块(django 框架自带)
python提供的,用于测试和学习的简单的WSGI服务器模块。
这个模块监听8000端口,把Http请求,根据WSGI协议,转换application函数中的environ参数,然后调用application函数。
wsgiref会把application函数提供的响应头设置转换为HTTP协议的响应头,把application的返回(return)作为响应体,
根据HTTP协议,生成响应,返回给浏览器。
uWSGI服务器
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
uWSGI的主要特点如下:
- 超快的性能
- 低内存占用(实测为apache2的mod_wsgi的一半左右)
- 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
- 详尽的日志功能(可以用来分析app性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
为什么要使用Nginx 来做负载均衡
Nginx
1 安全(Nginx 作为专业服务器,暴露在公网相对比较安全)
2 能更好地处理静态资源(一些http request header)
3 Nginx也可以缓存一些动态内容Nginx可以更好地配合CDN
4 可以进行多台机器的负载均衡
当然,如果访问量不大,其实也没必要加个Nginx,uWSGI足以胜任。
nginx与负载均衡
-
nginx (基于效率最高的 epoll IO 模型 ) 支持并发量 2w,
-
(它相当于是 精简版的 httpd) web 服务器
niginx 实现负载均衡:
实现方式: 反向代理
代理的类别
-
1 正向: vpn (正常的使用中间代理 来获取想要的数据)
-
2 反向(把内网的机器隐藏起来): 用户访问同一台机器(代理机器),然后把用户请求分发到不同的其他机器上,获取结果后再统一的返回给用户
反向代理:
用户pc --->> nginx 隐藏的内网的 机器 (也可以是nginx)
(反向代理) ---->> .A
同时实现了负载均衡 ---->> B
---->> C
---->> D
---->> .....
- 3 透明(管理用户) :(用户不知道代理的存在)
数据包-->> 交换机 -->> (管理员 设置 透明代理) 中间服务器(限制访问内容) -->> 正常网页
niginx 负载均衡的方式:(要考虑用户的状态维持)
-
(1)round-robin 轮询 默认每个机器一次
也可以加权重 (使得配置,性能好的机器更多的使用) 缺点:不能保持用户的状态
-
(2)使用 ip-hash (用户认证 使得会话保持)
但是这样 会没有负载均衡
-
(3)解决方法:使用一台第三方(共享的机器)的机器来专门 保存用户的 验证信息
Django项目部署
Django的settings中
settings --- ALLOWED_HOST = ['个人的IP']
DEBUG = False
(1)Django代码 拷贝到服务器(用自带的 wsgiref)**
runserver 0.0.0.0:9002 (自带的wsgiref 性能低)
(2) 通过uwsgi
pip install uwsgi
使用 :
a linux 下载 uwsgi 运行 app.py,监听 9001端口
单文件
app.py
def application(env,start_response):
start_response('200 OK',[('Content-Type','text/html')])
return [b'hello world']
启动
uwsgi --http :9001 --wsgi-file app.py
访问
http://140.143.35.239:9001/
hello world # 获取响应
b Django 程序(wsgi.py文件):
用uwsgi 启动django
uwsgi --http :8000 --module mysite.wsgi
也可以加配置
uwsgi --http :9005 --chdir /data/项目目录/ --wsgi-file /项目/wsgi.py --master --process 4 --threads 2 --static-map /static=/data/...c
含静态文件:
需要配置 STATIC_ROOT (用于统一收集静态文件)
收集静态文件 python manage.py collectstatic
Flask程序:
uwsgi --http :9002 --wsgi-file run.py --callable app
c 写一个 uwsgi.ini 配置文件(使用ini配置文件启动)
Django:
[uwsgi]
http = 0.0.0.0:9005
chdir = /data/项目目录/
wsgi-file = /项目/wsgi.py
process = 4
threads = 2
static-map = /static=/data/...c
uwsgi --ini dmysite_uwsgi.ini
Flask:
deploy_uwsgi.ini
[uwsgi]
http = 0.0.0.0:9005
chdir = /data/deploy/
wsgi-file = run.py
processes = 4
static-map = /static=/data/deploy/static
callable = app
uwsgi --ini deploy_uwsgi.ini
(3) nginx 反向代理(分发)
uwsgi 处理静态文件的能力不强
使用 -- yum install nginx
1 启动 uwsgi
uwsgi uwsgi_socket.ini
写一个 uwsgi_socket.ini 配置文件
[uwsgi]
socket = 0.0.0.0:9005
chdir = /data/项目目录/
wsgi-file = /项目/wsgi.py
process = 4
threads = 2
2 启动 nginx
/etc/init.d/nginx start
配置:nginx.conf
user root;
worker_processes 4;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
' "$http_user_agent" "$http_x_forwarded_for" ';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodeplay on;
keepalive_timeout 65;
# types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream django {
# servr unix://path/to/your/mysite.sock;
servr 127.0.0.1:9001;
}
server {
listen 80;
charset utf-8;
client_max_body_size 75M;
location /static{
alias /root/s5/sdads
}
location / {
uwsgi_pass django;
include uwsgi_params;
}
}
}
(4) 项目上线
1 vue --- vue run build (run build 来生成正式的静态文件) -->>> dist生成一个静态文件
2 上传到服务器 nginx的静态文件的目录
3 django restframework
location /api {
uwsgi_pass django;
include uwsgi_params;
}
location / {
alias /静态文件;
}
(5) 运维部署流程
开发 上传git
运维 :通过jekins 软件 --->> 自动化部署(git下载,上传到上线服务器)
saltstack管理工具
测试服务器 master
saltstack 推送到线上(vue--dist, api程序)
上线服务器 slave
正式的
静态文件目录 uwsgi的目录