**本章內容**:
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
終極神器:重啓重裝換機器