banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

【轉載】我希望多年前就知道的 Nginx 概念

title: 【轉載】我希望多年前就知道的 Nginx 概念
date: 2021-08-14 09:32:45
comment: false
toc: true
category:

  • 分享
    tags:
  • 轉載
  • nginx
  • 概念

本文轉載自:[譯] 我希望多年前就知道的 Nginx 概念


哇!複雜的術語和混亂的定義,裡面充斥著大量令人困惑的詞語,對吧?不用擔心,我可以幫大家先了解 Nginx 的基本架構和術語,然後我們將安裝並創建 Nginx 配置。

迷惑表情.gif

為了讓事情變簡單,只需要記住:Nginx 是一個神奇的 Web 伺服器

簡單來說,Web 伺服器就像個中間人。比如你想訪問 dev.to,輸入地址 https://dev.to,你的瀏覽器就會找出 https://dev.to 的 Web 伺服器地址,然後將其定向到後台伺服器,後台伺服器會把響應返回給客戶端。

代理 vs 反向代理#

Nginx 的基本功能是代理,所以現在就需要了解什麼是代理和反向代理。

代理#

好的,我們有一個或多個客戶端、一個中間 Web 伺服器(在這種情況下,我們稱它為代理)和一個伺服器。這其中最主要的事情是伺服器不知道哪個客戶端正在請求。是不是有點困惑?讓我用一張示意圖來解釋一下。

代理示意圖

在這種情況下,客戶端 client1 和 client2 通過代理伺服器向伺服器發送請求 request1 和 request2,後台伺服器不會知道 request1 是由 client1 還是 client2 發送的,只會執行操作。

反向代理#

用最簡單的話說,反向代理就是把代理的工作反過來。比方說有一個客戶端、一個中間 Web 伺服器和一個或多個後台伺服器。讓我們繼續通過一張示意圖解釋吧!

反向代理示意圖

在這種情況下,客戶端將通過 Web 伺服器發送一個請求,Web 伺服器會通過一種算法將請求定向到眾多伺服器的任意一個,其中一種算法是輪詢調度(Round-Robin)(最可愛的一個!),然後再將響應通過 Web 伺服器返回給客戶端。因此在這裡,客戶端並不知道與之互動的是哪一個後台伺服器。

負載均衡#

可惡,又是一個新詞,但是這個詞比較容易理解,因為它是反向代理 本身的一個實際應用。

我們先說說基本的區別。在負載均衡中,必須要有兩個或者更多的後台伺服器,但在反向代理設置中,這不是必須的,它甚至可以只跟單台後台伺服器一起使用。

讓我們從幕後看一下,如果我們有大量來自客戶端的請求,這個負載均衡器會檢查每個後台伺服器的狀態並分配請求的負載,然後將響應更快地發送給客戶端。

有狀態應用 vs 無狀態應用#

好的各位,我保證我很快就要講到 Nginx 代碼了,先讓我們把所有的基本概念搞清楚!

有狀態應用#

這個應用程序存儲了一個額外的變量,用於保存只適用於單個伺服器實例的信息。

有狀態應用圖例

我的意思是,如果後端伺服器 server1 存儲了一些信息,那麼它不會被存儲在 server2 上,因此進行互動的客戶端(這裡指 Bob)可能得不到想要的結果,因為它可能會與 server1 或者 server2 互動。在這種情況下,server1 將允許 Bob 查看配置文件,但 server2 不會允許。因此,即使有狀態應用阻止了許多 API 調用數據庫,並且速度更快,但卻可能會在不同伺服器上導致上述問題。

無狀態應用#

現在,無狀態是對數據庫的 API 調用更多,但客戶端與不同後台伺服器互動時,存在的問題就更少了。。

無狀態應用圖例

我知道你沒有明白我的意思。簡單來說,如果我從客戶端通過 Web 伺服器向比如說後台伺服器 server1 發送一個請求,它將向客戶端提供一個令牌以用於訪問其他任何請求。客戶端可以使用令牌並將請求發送給 Web 伺服器,該 Web 伺服器將請求和令牌一起發送給任意後台伺服器,每個伺服器都將返回相同的期望輸出。

什麼是 Nginx?#

Nginx 就是 Web 伺服器,到目前為止,我一直在整篇博客中使用 Web 伺服器這個詞,老實說,它就像一個中間人

Nginx 示意圖

這張圖並不難懂,它只是結合了我到現在為止解釋的所有概念。在這張圖中,我們有 3 台分別運行在 3001、3002、3003 端口的後台伺服器,這些後台伺服器共同使用運行在 5432 端口的數據庫。

現在,當客戶端向 https://localhost(默認 443 端口)發送請求 GET /employees 時,Nginx 將根據算法把這個請求發送給任意一個後台伺服器,後台伺服器從數據庫中獲取信息,然後把 JSON 結果發送回 Nginx Web 伺服器,Nginx 再發送回客戶端。

如果我們要使用諸如輪詢調度 這樣的算法,Nginx 會這樣做:比如 client2 發送了一個請求到 https://localhost,那麼 Nginx 伺服器會先把請求傳到 3001 端口,然後把響應返回給客戶端。對於另一個請求,Nginx 會把請求傳到 3002 端口,以此類推。

這也太多概念了吧!但是到此為止,你應該已經清楚地了解了什麼是 Nginx 及其相關術語。現在,我們將繼續了解 Nginx 的安裝和配置。

安裝過程#

終於到這一步了!如果你能理解 Nginx 概念並看到了代碼這部分,那真是棒棒哒!

十分感動.gif

好的,老實說,在任何操作系統上安裝 Nginx 都只需要一行命令。我是 Mac OSX 用戶,所以會基於它來寫命令。但對於 UbuntuWindows 以及其他 Linux 發行版,也有類似的命令。

brew install Nginx

只需要一行命令,你的系統就已經安裝上 Nginx 了!非常 Amazing!

運行 So easy!😛#

運行下面的命令來檢查 Nginx 是否在你的系統上運行起來了,又是非常簡單的一步。

nginx 
# OR 
sudo nginx

運行完命令之後,使用你最喜歡的瀏覽器訪問 http://localhost:8080/,你將在屏幕上看到下面的畫面!

Nginx 網頁

基本配置和示例#

好的,我們將通過一個示例來展示 Nginx 的神奇之處。首先,在本地機器上創建如下的目錄結構:

.
├── nginx-demo
│  ├── content
│  │  ├── first.txt
│  │  ├── index.html
│  │  └── index.md
│  └── main
│    └── index.html
└── temp-nginx
  └── outsider
    └── index.html

同時,在 htmlmd 文件中寫上基本的上下文內容。

我們要達到什麼效果?#

在這裡,我們有兩個單獨的文件夾 nginx-demotemp-nginx,每個文件夾都包含靜態 HTML 文件。我們將專注於在一個共同端口上運行這兩個文件夾,並設置我們喜歡的規則。

現在回到正軌。我們可以通過修改位於 /usr/local/etc/nginx (譯者注:默認安裝路徑)路徑下的 nginx.conf 文件,實現對 Nginx 默認配置的任何改動。另外,我的系統中有 Vim,所以我將用 Vim 進行修改,你也可以自由使用所選的編輯器。

cd /usr/local/etc/nginx
vim nginx.conf

這將打開一個默認的 Nginx 配置文件,但我真的不想使用它的默認配置。因此,我通常會複製這個配置文件,然後對原文件進行修改。在這裡我們也這樣做。

cp nginx.conf copy-nginx.conf
rm nginx.conf && vim nginx.conf 

現在打開一個空文件,我們將給它添加我們的配置。

  1. 添加一個基本配置。添加 events {} 是必須的,因為對於 Nginx 架構來講,它通常被用來表示 Worker 的數量。我們在這裡使用 http 來告訴 Nginx,我們將使用 OSI 模型 的第 7 層。
    在這裡,我們讓 Nginx 監聽 5000 端口,並指向 /nginx-demo/main 文件夾下的靜態文件。

    http {
    
        server {
            listen 5000;
            root /path/to/nginx-demo/main/; 
            }
    
    }
    
    events {}
    
  2. 接下來我們將對 /content/outsider URL 添加額外的規則,其中 outsider 將指向第一步中提到的根目錄(/nginx-demo)以外的目錄。
    這裡 location /content 表示無論我在子目錄中定義了哪一個根目錄,content 子 URL 都會被添加到定義的根目錄末尾。因此,這裡當我指定根目錄為 root /path/to/nginx-demo/ 時,僅僅表示我告訴 Nginx 在 http://localhost:5000/path/to/nginx-demo/content/ 向我展示文件夾內靜態文件的內容。

    http {
    
        server {
            listen 5000;
            root /path/to/nginx-demo/main/; 
    
            location /content {
                root /path/to/nginx-demo/;
            }   
    
            location /outsider {
                root /path/temp-nginx/;
            }
        }
    
    }
    
    events {}
    

    好酷!現在 Nginx 不僅限於定義根 URL,還可以設置規則,以便於我可以阻止客戶端訪問某些文件。

  3. 我們將在定義的主伺服器中寫入一條附加規則,用來阻止訪問任何 .md 文件。我們可以在 Nginx 中使用正則表達式,規則定義如下:

    location ~ .md {
        return 403;
    }
    
  4. 最後我們來學習一下流行的命令 proxy_pass。現在我們已經了解了什麼是代理和反向代理,這裡我們先定義另一個運行在 8888 端口的後台伺服器,所以現在我們已經有了 2 個分別運行在 5000 和 8888 端口的後台伺服器。
    我們要做的是,當客戶端通過 Nginx 訪問 8888 端口時,將這個請求傳到 5000 端口,並向客戶端返回響應!

    server {
        listen 8888;
    
        location / {
            proxy_pass http://localhost:5000/;
        }
    
        location /new {
            proxy_pass http://localhost:5000/outsider/;
        }
    }
    

最後一起來看看完整的代碼!😁#

http {

    server {
        listen 5000;
        root /path/to/nginx-demo/main/; 

        location /content {
            root /path/to/nginx-demo/;
        }   

        location /outsider {
            root /path/temp-nginx/;
        }

                location ~ .md {
            return 403;
        }
    }

    server {
        listen 8888;

        location / {
            proxy_pass http://localhost:5000/;
        }

        location /new {
            proxy_pass http://localhost:5000/outsider/;
        }
    }
}

events {}

通過 sudo nginx 來運行代碼。

額外的 Nginx 命令!#

  1. 首次啟動 Nginx Web 伺服器。

    nginx 
    #OR 
    sudo nginx
    
  2. 重新加載正在運行的 Nginx Web 伺服器。

    nginx -s reload
    #OR 
    sudo nginx -s reload
    
  3. 關閉正在運行的 Nginx Web 伺服器。

    nginx -s stop
    #OR 
    sudo nginx -s stop
    
  4. 查找有哪些 Nginx 進程正在系統中運行

    ps -ef | grep Nginx
    

第 4 條命令很重要,當前 3 條命令出現錯誤時,可以使用第 4 條命令找到所有正在運行的 Nginx 進程,然後 kill 掉這些進程,重新啟動 Nginx 服務。

要 kill 一個進程,你需要先知道它的 PID,然後用下面的命令 kill 它:

kill -9 <PID>
#OR 
sudo kill -9 <PID>

在結束這篇文章之前,聲明一下我所使用圖片和視覺效果來自 Goole 圖片和由 Hussein Nasser 提供的 Youtube 教程。

關於 Nginx 的基本認識和配置,我們就講到這裡。如果你對 Nginx 的進階配置感興趣,請通過評論告訴我。在此之前,請享受編程的樂趣,探索 Nginx 的魔力!👋

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計畫 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久鏈接 即為本文在 GitHub 上的 MarkDown 鏈接。


掘金翻譯計畫 是一個翻譯優質互聯網技術文章的社區,來源文章為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計畫官方微博知乎專欄

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。