Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負載均衡操作

2023-12-11 06:00:41

本文首發於公眾號:Hunter後端

原文連結:Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負載均衡操作

這一篇筆記介紹如何使用 Nginx + uWSGI 來部署 Django。

上一篇筆記中有介紹直接使用 uWSGI 作為 web 伺服器來部署 Django,這一篇筆記介紹如何使用 Nginx 來部署。

使用 Nginx 來部署相當於在 uWSGI 外面又巢狀了一層,uWSGI 作為內部服務被隱藏起來,這時候 Nginx 起的作用是反向代理。

在這裡,Nginx 的安裝操作就不贅述了,網上都可以找得到如何操作,這裡只講相關的設定操作。

以下是本篇筆記目錄:

  1. uWSGI 設定
  2. Nginx 設定及其作用
  3. Nginx 實現負載均衡

1、uWSGi 設定

我們還是複用上一篇筆記中的 Django 系統程式碼和 uWSGI 設定

# uwsgi.ini

[uwsgi]
socket = :9898
chdir = /path/to/hunter/
wsgi-file = hunter/wsgi.py
master=true
processes = 4
threads = 2

注意,這裡設定項的第一行已經從 http 改成了 socket

如果使用 http,表示我們將 uWSGI 直接作為一個 web 伺服器,比如可以在瀏覽器存取相關介面。

如果使用 socket,表示會有比如 Nginx 一樣的服務來作為 web 伺服器,這個時候 uWSGI 起到類似中介軟體的作用,負責將來自 web 伺服器的請求解析後轉發給 Django 來處理。

2、Nginx 設定及其作用

在我這裡,Nginx 的相關設定在 /etc/nginx/nginx.conf

Nginx 的設定如下:

http {
    
    server {
        listen 8900;

        location / {
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:9898;
            uwsgi_read_timeout 2;
        }
    }
}

這裡,listen 表示 Nginx 對外開放的是 8900 埠

location 表示的是定義的路由,這裡是 /,表示 8900 埠後可以直接接上 Django 系統的 api 介面。我們也可以改成其他的,比如 /backend,那麼存取 Django 的每一個介面字首都要加上 /backend

其下,uwsgi_pass 表示指向的是本機的 9898 埠服務,這裡和我們 uWSGI 裡的設定是一致的

uwsgi_read_timeout 表示的是超時時間,這裡定義的是兩秒。

接下來我們啟動 uWSGI 服務和 Nginx 服務:

uwsgi uwsgi.ini

sudo /etc/init.d/nginx restart

這時候存取 Nginx 所在的 地址的 8900 埠,http://192.168.1.33:8900/admin,就可以存取我們的 Django 系統了。

如果想要 admin 頁面有前端樣式展示,記得新增 uwsgi.ini 上篇筆記中的對應的靜態檔案設定。

3、Nginx 實現負載均衡

在上面的操作中,一個請求從使用者端到 Nginx,再到 uWSGI 和 Django,這個過程就是反向代理。

而如果請求量過大,一個 uWSGI 和 Django 和對應的資料庫可能扛不住存取壓力,所以需要增設多個後端來分擔請求,這個就是負載均衡。

首先介紹一下負載均衡的幾種策略:

  • 輪詢
  • 加權
  • ip hash

這裡假設我們起了三個後端範例,ip 和埠分別是 192.168.1.31:9898、192.168.1.33:9898、192.168.1.144:9898

1. 輪詢

所謂的輪詢,就是按照請求的時間順序逐個分配到指定的這三個後端服務上,這裡 Nginx 的設定如下:

http {
    upstream web {
        server 192.168.1.31:9898;
        server 192.168.1.33:9898;
        server 192.168.1.144:9898;
    }
    
    server {
        listen 8900;

        location / {
            proxy_pass http://web;
        }
    }
}

上面的這種方式設定之後,重啟 Nginx 和 uWSGI 之後,就會通過輪詢的方式來傳送請求到三個 Django 服務了。

注意:上面的設定方式,proxy_pass 表示是基於 http 協定進行請求的,也就是說 Nginx 到 uWSGI 走的是 http 協定,我們需要將 uwsgi.ini 的設定改成 http=:9898

如果要走之前的 uwsgi 協定請求方式,需要將 Nginx 的這裡改成這樣:

    server {
        listen 8900;

        location / {
            include uwsgi_params;
            uwsgi_pass web;
        }

2. 加權

加權就是可以人為控制到幾個伺服器請求的數量的佔比,比如對於這三個後端,想要請求到它們的請求的數量比為 1:2:3,可以這樣設定:

    upstream web {
        server 192.168.1.31:9898 weight=1;
        server 192.168.1.33:9898 weight=2;
        server 192.168.1.144:9898 weight=3;
    }

這樣,來六個請求的話,這三個後端分配到的請求數量分別是 1,2,3個。

3. ip hash

這是根據使用者端地址來進行分配的一個操作,假設某個請求的 ip 是 192.168.1.59,這時候 Nginx 會根據 ip 計算一個值之後對映到三個後端服務的某一個,在之後的每次請求都會指向這個後端服務。

其設定如下:

    upstream web {
        ip_pash;
        server 192.168.1.31:9898;
        server 192.168.1.33:9898;
        server 192.168.1.144:9898;
    }

如果使用 ip hash 策略,來自某個使用者端的請求都會定向指向某個後端服務,因此可以不用擔心解決後端服務共用 session 的問題。

注意:因為需要處理 session 共用的問題,所以在上面的測試中,我這邊都是直接存取的不用登入,也就是不用擔心 session 問題的介面。

在實際的負載均衡的後端服務中,session 的共用,使使用者保持登入狀態而無感,是一個需要解決的問題,這個在之後有機會的話再開筆記詳細講述。

如果想獲取更多相關文章,可掃碼關注閱讀: