HTTPS+Nginx+uWSGI(HA)+Django服務部署


**本章內容**:
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

終極神器:重啓重裝換機器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章