**本章内容**:
1: Nginx 简述
2: uWSGI 简述
3: uWSGI + Django服务部署
4: Nginx + uWSGI + Django服务部署
5: Https + Nginx + uWSGI + Django服务部署
6: uWSGI + HA 服务部署
1. Nginx简述
Nginx(异步事件处理模型) VS Apache(多线程客户机处理模型)
Nginx性能强劲(5W并发连接)、并发处理能力更强
1.1 Nginx关键配置模块
event配置域: 网络连接相关配置(I/O模型等)
server配置域:相关服务节点配置
location配置域:资源路由配置
http配置域:Nginx作为网页服务器时的配置
upstream配置域:反向代理配置域
1.2 层次关系
worker_processes auto; # 多少个工人进程
events{
worker_connections 768; # 每个进程可以处理多少个连接
}
http{
upstream{
} # 定义主机域server{
# 主机实例,基于域名/ip/端口location{
} # 资源定位}
}
#mail{
}
1.3 nginx 安装
[root@node ~]# wget http://nginx.org/download/nginx-1.12.2.tar.gz
[root@node ~]# tar -zxvf nginx-1.12.2.tar.gz && cd nginx-1.12.2
[root@node ~]# ./configure
[root@node ~]# make && make install
[root@node ~]# ln -s /usr/local/nginx/bin/nginx /usr/bin/local/nginx
1.4 nginx 使用
[root@node ~]# nginx # 启动
[root@node ~]# nginx -s stop # 关闭
2. WSGI协议
全称:Web Server Gateway Interface( 服务器网关接口 )
Web Server和Web Application通信的规范
2.1 uWSGI概述
uWSGI实现了WSGI协议,是一个Web服务器,主要功能为接收客户端请求通过协议传达Django应用。
2.2 uWSGI安装与基本配置
安装:
[root@node ~]# pip3 install uwsgi
[root@node ~]# ln -s /usr/local/python3/bin/uwsgi /usr/local/bin/uwsgi
2.2.1 关键字:
chdir:指定WSGI应用目录
module:指定WSGI应用的模块名字
processes:指定uWSGI进程数
(http-)socket:套接字路径、地址
max-requests:最大并发请求数
vacuum:清理环境配置(Boolen),当服务器退出的时候,是否删除相关socket文件和pid文件,默认配置为true
2.2.2 命令行启动
[root@node ~]#uwsgi --chdir xxx --socket :80 --max-requests 5000 --processes 4 --module xxx.wsgi
2.2.3 配置文件启动
[root@node ~]# cat uwsgi-demo.ini
[uwsgi]
chdir = /xxx/xx
http-socket = :80
max-requests = 5000
processes = 4
module = xxx.wsgi
[root@node ~]# uwsgi --ini uwsgi-demo.ini
2.2 为什么需要uWSGI部署DJango应用?
- Django runserver 可以直接对外服务,但只是用于测试,不安全性能差;
- uWSGI可以很好的进行多线程调度、进程监控;例如可以检测Django进程是否阻塞,挂了,若挂了,uWSGI具备重启Django应用的能力;
- uWSGI提供完善的请求日志处理,例如可以提供客户端ip、http报文。
3.部署uWSGI+ Django服务
3.1 部署Web Client + uWSGI + Python
测试
[root@node hhx]# mkdir deployment && cd deployment
[root@node deployment]# vim uwsgi_test.py
#!/usr/bin/env python3
# -*- encoding=utf-8 -*-def application(env, start_response):start_response('200 OK', [('Content-type','text/html')])return [b'Hello World, Hello uWSGI.']
[root@node deployment]# uwsgi --http :8000 --wsgi-file uwsgi_test.py
[root@node deployment]# curl localhost:8000
3.2 部署Web Client + uWSGI + Django
[root@node deployment]# ln -s /usr/local/python3/bin/django-admin /usr/local/bin/django-admin
[root@node deployment]# django-admin startproject django_deployment
[root@node deployment]# cd django_deployment
[root@node django_deployment]# ls django_deployment/wsgi.py
django_deployment/wsgi.py
[root@node django_deployment]# uwsgi --http :8000 --module django_deployment.wsgi
[root@node django_deployment]# curl localhost:8000
Django
The install worked successfully! Congratulations!
......
3.2.1 改用配置文件启动
[root@node django_deployment]# ls
db.sqlite3 django_deployment manage.py
[root@node django_deployment]# pwd
/home/hhx/deployment/django_deployment
[root@node django_deployment]# vim django-uwsgi.ini
[uwsgi]
chdir = /home/hhx/deployment/django_deployment
module = django_deployment.wsgi
http-socket = :8000
master = True
processes = 4
threads = 1
vacuum = True
[root@node django_deployment]# uwsgi --ini django-uwsgi.ini
[root@node django_deployment]# curl localhost:8000
Django
The install worked successfully! Congratulations!
3.2.2 改用后台形式启动
[root@node django_deployment]# vim django-uwsgi.ini
...
vacuum = True
# backend run uwsgi, set size 1G
daemonize = %(chdir)/log/uwsgi-8000.log
log-maxsize = 1073741824
pidfile = %(chdir)/pid/uwsgi-8000.pid
[root@node django_deployment]# mkdir log && mkdir pid
[root@node django_deployment]# uwsgi --ini django-uwsgi.ini
[uWSGI] getting INI configuration from django-uwsgi.ini
3.2.3 启动终端观察访问日志
[root@node django_deployment]# watch -n1 cat log/uwsgi-8000.log
或者
[root@node django_deployment]# tail -f log/uwsgi-8000.log
3.2.4 Client访问Web
[root@node django_deployment]# curl localhost:8000
3.2.5 关闭uwsgi
[root@node django_deployment]# cat pid/uwsgi-8000.pid
115681
[root@node django_deployment]# uwsgi --stop pid/uwsgi-8000.pid
4. Nginx + uwsgi + Django服务部署
4.1 为什么还需要Nginx进行部署?
- Nginx提供了更安全的服务保障
- 提供反向代理、负载均衡等功能
- 对于静态文件的处理能力更强
4.2 Nginx + uwsgi + Django服务部署
4.2.1 uWSGI启动Django应用服务(启动请看本章第三节)
4.2.2 修改Nginx配置文件,完成反向代理配置
[root@node ~]# find / -name 'nginx.conf'
/usr/local/nginx/conf/nginx.conf
[root@node ~]# cat /usr/local/nginx/conf/nginx.conf |grep -v ^$ | egrep -v '\s#' | grep -v ^#
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;upstream uwsgi {
server 127.0.0.1:8000;}server {
listen 80;server_name .python3.com;charset utf-8;access_log logs/uwsgi.access.log;location / {
proxy_pass http://uwsgi; }error_page 500 502 503 504 /50x.html;location = /50x.html {
root html;}}
}
[root@node ~]# nginx
[root@node ~]# echo 127.0.0.1 python3.com >> /etc/hosts
[root@node ~]# curl python3.com
[root@node ~]# tail -f /usr/local/nginx/log/uwsgi.access.log
127.0.0.1 - - [04/Mar/2019:15:51:34 +0800] "GET / HTTP/1.1" 200 16559 "-" "curl/7.29.0"
但是浏览器访问是这样子的,由于nginx无法链接到django的静态资源。
4.2.3 收集Django静态文件
[root@node django_deployment]# echo 'STATIC_ROOT=os.path.join(BASE_DIR,'static/')' >> django_deployment/settings.py
[root@node django_deployment]# python3 manage.py collectstatic
118 static files copied to '/home/hhx/deployment/django_deployment/static'.
[root@node django_deployment]# mv /home/hhx/deployment/django_deployment/static /usr/local/nginx/
4.2.4 Nginx配置静态文件寻址
[root@node django_deployment]# cd /usr/local/nginx/conf && cp nginx.conf nginx.conf.bak
[root@node conf]# chown -R nobody:nobody static
[root@node conf]# vim nginx.conf # 添加新内容
新增内容对比
[root@node conf]# diff nginx.conf nginx.conf.bak
61,63d60
< location /static {
< alias static;
< }
再次访问
5. HTTPS服务部署
5.1 创建证书、密钥
[root@node ~]# cd /usr/local/nginx/conf/ && mkdir cert && cd cert
[root@node cert]# openssl genrsa -out cert.key 2048
[root@node cert]# openssl req -new -x509 -key cert.key -out cert.pem -days 3650 -subj /CN=www.python3.com
5.2 修改配置后如下
[root@node cert]# cat ../nginx.conf | grep -v ^$ | egrep -v '#'
user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;upstream uwsgi {
server 127.0.0.1:8000;}server {
listen 80;server_name .python3.com;return 301 https://$host$request_uri;}server {
listen 443 ssl;server_name .python3.com;charset utf-8;ssl_certificate cert/cert.pem;ssl_certificate_key cert/cert.key;ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;ssl_ciphers HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers on;access_log log/https-uwsgi.log;location / {
proxy_pass http://uwsgi;}location /static {
alias static;}}
}
5.3 启动nginx,访问web,查看日志
[root@node ~]# tail -f /usr/local/nginx/logs/https-uwsgi.log
127.0.0.1 - - [04/Mar/2020:20:42:00 +0800] "GET /static/admin/css/responsive.css HTTP/1.1" 200 17894 "https://python3.com/admin/login/?next=/admin/" "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"
6. uWSGI HA 服务部署
6.1 开启两个uWSGI进程
[root@node ~]# cd /home/hhx/deployment/django_deployment
[root@node django_deployment]# cp django-uwsgi.ini django-uwsgi-8001.ini
[root@node django_deployment]# cp django-uwsgi.ini django-uwsgi-8002.ini
[root@node django_deployment]# uwsgi --stop pid/uwsgi-8000.pid
[root@node django_deployment]# diff django-uwsgi-8001.ini django-uwsgi-8002.ini
4c4
< http-socket = 127.0.0.1:8001
> http-socket = 127.0.0.1:8002
11c11
< daemonize = %(chdir)/log/uwsgi-8001.log
> daemonize = %(chdir)/log/uwsgi-8002.log
13c13
< pidfile = %(chdir)/pid/uwsgi-8001.pid
> pidfile = %(chdir)/pid/uwsgi-8002.pid
[root@node django_deployment]# uwsgi --ini django-uwsgi-8001.ini
[uWSGI] getting INI configuration from django-uwsgi-8001.ini
[root@node django_deployment]# uwsgi --ini django-uwsgi-8002.ini
[uWSGI] getting INI configuration from django-uwsgi-8002.ini
6.2 修改Ngiinx配置后重启
[root@node django_deployment]# cd /usr/local/nginx/conf
[root@node conf]# cp ngiinx.conf nginx.bak
[root@node conf]# vim nginx.conf
修改前后对比
[root@node conf]# diff nginx.conf nginx.bak
36,38c36
< server 127.0.0.1:8001 weight=100 max_fails=2 fail_timeout=15s;
< server 127.0.0.1:8002 weight=50 max_fails=2 fail_timeout=15s;
< # server 127.0.0.1:8003 weight=100 max_fails=2 fail_timeout=15s backup;
> server 127.0.0.1:8000;
[root@node conf]#nginx -s reload
6.3 测试
6.3.1 uwsgi按权重负载均衡测试
分别开两个终端A、B
终端A
[root@node django_deployment]# taif -f log/uwsgi-8001.log
终端B
[root@node django_deployment]# taif -f log/uwsgi-8002.log
连续访问web,观察终端A/B:均有数据输出,输出记录为A:B = 2:1
6.3.2 uwsgi单点故障测试
[root@node django_deployment]# uwsgi --stop pid/uwsgi-8001.pid
连续访问web,观察终端A/B:只有终端B有数据输出
附录:DEBUG命令
ps -aux| grep uwsgi
ps -aux| grep nginx
netstat -anultp | grep uwsgi
netstat -anultp | grep nginx
cat /usr/local/nginx/logs/error.log
终极神器:重启重装换机器