Nginx 是什麼?認識反向代理、負載平衡

古古

2024/09/10


Nginx 可以說是在大型的微服務架構中,必備的核心功能之一,所以這篇文章我們就來介紹一下 Nginx 到底是什麼,以及介紹一下反向代理、負載平衡的概念吧!

什麼是 Nginx? #

Nginx 是一個輕量級的 Web 伺服器,通常用在以下三種情境:

  • 反向代理(Reverse Proxy)
  • 負載平衡(Load Balancing)
  • Http Cache

不過在我們開始了解 Nginx 的這三種特性之前,要先回頭來介紹一下 Nginx 最一開始要解決的問題是什麼,了解了 Nginx 要解決的問題之後,我們才能夠延伸去介紹「反向代理」、「負載平衡」、以及「Http Cache」的概念。

補充:Nginx 的唸法是「Engine X」(中文發音近似於「安金 欸可斯」),也就是「引擎 X」的意思,這裡開頭的 N 字母就是使用到英文語法中常見的縮寫。像是 How are you 可以簡寫成 How r u、而 Airbnb 其實是 AirBed & Breakfast 的簡寫(n 的發音近似於 &),所以在這裡就是用到了英文的語法,將「Engine X」縮寫為「Nginx」。

在 Nginx 被發明出來之前:單體式架構 #

在我們一開始學習後端程式時,我們就是寫好一個後端程式(ex: Spring Boot 程式),然後運行他,接著我們就可以用 Postman 這類的工具,去發起一個 API call,去請求我們電腦上所運行的後端程式,而這個就是最簡單的 單體式架構(Monolithic),也就是同時間我們只會有一個後端程式存在。

不過當有越來越多使用者,慕名前來使用我們的後端服務時,這時候就會導致流量上升,使得一台 Server 沒辦法支撐住這麼高的流量。

所以這時候,為了確保 Server 能負擔這麼高的流量,我們就有兩個選擇:

  1. 使用 Vertical Scaling(垂直擴展),為這台 Server 升級 cpu、ram…等設備,讓他從一台普通的「2 核 cpu、4 GM ram」的電腦,變成是一台「64 核 cpu、128 GB ram」的超級電腦。
  2. 使用 Horitontal Sclaing(水平擴展),也就是多新增幾台 Server 出來,大家人多勢眾,一起對付更高的流量。

如果這時我們選擇 Vertical Scaling(垂直擴展)的話,就只是從一台普通的 Server,進化成一台超級電腦而已。這個選擇對整體的架構沒有影響,仍舊是只有一個後端程式在運行,所以此時依舊是單體式的架構,因此不需要 Nginx 上場。

但如果我們選擇的是 Horitontal Sclaing(水平擴展)的話,那麼我們在同一時間,就會有非常多台的 Server 聚集在一起,準備聯合起所有 Server 的力量,一起對付高流量。所以這時候,整個後端的架構,就會從「單體式架構(Monolithic)」變成「微服務架構(Microservices)」,也就是同時間有多個後端程式在運作。

所以這個時候,我們就會遇到微服務架構所要面對的問題,因此就需要 Nginx 上場了!

補充:如果想更了解 Vertical Scaling(垂直擴展)和 Horizontal Scaling(水平擴展)的介紹,可以參考 Vertical Scaling 和 Horizontal Scaling 介紹 文章的介紹。不過這邊只要先知道 Horizontal Scaling 的概念是新增許多台 Server 出來,就可以繼續閱讀本文對 Nginx 的介紹了。

微服務架構所碰到的問題 #

在微服務的架構中,因為同時間會有多個後端 Server 在運作,所以這時候對於前端而言,最最最大的問題,就是他不知道要去 call 哪一台 Server 的 API(對這個聽起來有點笨,但是前端就真的不知道啊!)。

像是在下面這張圖中,同時間有 3 台後端 Server 在運作,這時候前端就會很困惑,他現在到底是要請求哪一台 Server?或是當流量又升高之後,這時候我們添加到 10 台 Server 來處理時,這時候要怎麼通知前端,現在有 10 台 Server 可以接受前端的請求?

所以為了解決這個問題,Nginx 就被發明出來了!

Nginx 的反向代理 #

Nginx 其中的一個核心功能,就是 「反向代理(Reverse Proxy)」,而所謂的反向代理,就是讓 Nginx 一個人擋在所有後端程式的最前面,由 Nginx 作為統一的守門人。

所以當前端想要來請求後端的 API 時,前端就會改成請求 Nginx,由 Nginx 決定這一次的請求要分配到哪一台後端 Server 上,而這個行為,就是反向代理(Reverse Proxy)了!

所以有了 Nginx 之後,Nginx 就可以作為所有後端 Server 的守門人,因此今天當前端來請求後端的 API 時,前端就必須改成去 call Nginx,由 Nginx 將這個請求「轉發」給任一台後端 Server(轉發規則由 Nginx 說了算),達到反向代理的效果。

所以透過 Nginx 的反向代理,我們就可以統一的處理所有前端傳遞過來的請求了!

Nginx 介紹 #

透過上面的例子大概了解 Nginx 的概念之後,我們也可以回頭正式來介紹一下 Nginx 的用途。

Nginx 是一個輕量級的 Web 伺服器,通常用在以下三種情境:

  • 反向代理(Reverse Proxy)
  • 負載平衡(Load Balancing)
  • Http Cache

而透過上述的例子,現在我們也了解了反向代理的概念是什麼:

反向代理(Reverse Proxy) #

所謂的「反向代理」,其實就只是 Nginx 一個人擋在所有後端 Server 的最前面,由 Nginx 作為後端 Server 的守門人,因此所有前端傳遞過來的請求,都一定都要先經過 Nginx,再經由 Nginx 後續去轉發給內部的後端 Server。

而使用反向代理的好處非常多,因為在反向代理中,是由 Nginx 一個人扛住所有對外的連接,所以我們只需要在 Nginx 中設定好 Https 的憑證即可,因此內部的後端 Server 就不需要處理網路相關的憑證問題。

又像是防火牆的問題,我們只要統一的在 Nginx 處理好 DDoS 之類的駭客攻擊就好,就不需要每一個後端 Server 都去處理,也大大的節省了資訊安全的維護成本。

如果大家有用過 AWS、GCP…這類雲端服務的話,其實 AWS 中的 API Gateway ,就會擋在 Amazon EC2 前面(EC2 就是 AWS 中提供 VM 的服務),由 API Gateway 統一處理所有對外的溝通。所以如果你的 Server 是部署在 AWS 上的話,那麼可以直接選擇 AWS 的 API Gateway 來負責反向代理的部分,因此就不用自己架一台 Nginx 來維護了。

圖片來源: Amazon API Gateway

負載平衡(Load Balancing) #

只要講到反向代理,那麼就一定會提到 負載平衡(Load Balancing),他們是必定會一起出現的一對名詞。

在前面我們有提到,Nginx 會作為所有後端 Server 的守門人,透過反向代理的機制,將前端傳過來的請求,「轉發」 給任一台後端 Server 上。

所以換句話說的話,今天這個請求會轉發到哪一台後端 Server 上,完全是看 Nginx 心情,假設 Nginx 沒設定好的話,可能就會導致每一個請求都轉發到同一台後端 Server 上,造成「一台有難,其他台隔岸觀火」的情況,而這個情形是我們不想看見的。

所以為了讓 Nginx 在轉發請求時,能盡量轉發的更平均一點,也就是讓每一台 Server 都有在工作,不會某一台過勞,這就是負載平衡的目的了!

所以所謂的 負載平衡(Load Balancing),就是一種將流量平均分配到後端 Server 的方法,讓每一台後端 Server 都可以被均等使用。

而在 Nginx 中,常見的負載平衡演算法有:

1. Round Robin 演算法(Nginx 預設使用此演算法): 所謂的 Round Robin,就是 Nginx 會照順序一台一台發送請求,所以就會變成第一個請求轉發給第一台 Server、第二個請求轉發給第二台 Server…等等,依此類推。運行邏輯可參考下圖中的 1. Round Robin 所描述。

2. Least Connected 演算法: 當請求來時,Nginx 查看目前哪一台 Server 負責的請求數最少,就轉發給他。運行邏輯可參考下圖中的 5. Least Connections。

3. IP Hash 演算法: Nginx 會取得請求發起方的 IP 地址,然後 hash 一下這個 IP 地址之後,將這個請求轉發到 hash 出來的 Server 上。運行邏輯可參考下圖中的 4. IP/URL Hash。

圖片來源: ByteByteGo - EP47: Common Load-balancing Algorithms

當然上面提到的這 3 種負載平衡的演算法,僅是 Nginx 所提供的演算法而已,如果大家使用的是 AWS 的 API Gateway 的話,有提供更多種的負載平衡演算法讓大家選擇,詳情可以參考 AWS 的《What is Load Balancing?》介紹

Http Cache #

除了上述的「反向代理」以及「負載平衡」的強大功能之外,Nginx 的最後一個特性,即是「Http Cache」。

像是我們可以把一些靜態的資源(ex: HTML 檔案、圖片)放在 Nginx 中,由 Nginx 儲存在 Http 的 Cache 中,這樣子當下次前端來請求靜態資源時,Nginx 就可以直接回傳這些靜態資源給前端,就不需要後端 Server 的介入了。

不過老實說,現在這個 Http Cache 的功能,已經被其他更厲害的工具(ex: CDN)給取代了,所以在實務上,不會真的去使用 Nginx 本身的 Http Cache 的功能,因此建議大家對這部分有個概念就可以了。

Nginx 總結 #

所以透過上面的介紹,現在我們就了解到,Nginx 是一個輕量級的 Web 伺服器,並且他通常會用在以下三種情境:

  • 反向代理(Reverse Proxy)
  • 負載平衡(Load Balancing)
  • Http Cache

其中「反向代理」和「負載平衡」這兩個核心功能,是 Nginx 最強大的地方,就是因為 Nginx 提供了「反向代理」和「負載平衡」的功能,所以我們才能夠將 Nginx 應用在微服務架構上,進而解決統一眾多後端 Server 入口的問題了!

補充:什麼是正向代理(Forward Proxy)? #

在上述的介紹中我們有提到,Nginx 擅長的部分是「反向代理」,也就是將後端 Server 隱藏起來,統一只由 Nginx 作為對外的出口,所以所有的前端請求都必須要經過 Nginx,才能夠到達內部的後端 Server。

而有反向代理,就會有正向代理(但老實說他們之間沒什麼關係),既然我們都談到了反向代理,就順便一起補充正向代理給大家。

所謂的 正向代理(Forward Proxy),就是將 Client 的資訊隱藏起來,由代理人統一的對外溝通。

像是公司的內網,一定是所有人的電腦先連線到 IT 所架設的路由器上,最終才由這個路由器出去對外和外部的網路世界溝通,所以在這個情境中,這個 IT 所架設的路由器就是負責「正向代理」,也就是所有 Client 所發出的請求,都會經過這個路由器,最終才會連線到真實的網路世界。

所以這也是為什麼大家在工作時,常常會遇到某些網站被公司 IT 給擋住,這就是因為所有的網路請求,實際上都會經過 IT 的路由器,最終才會傳到外部的公開網路上,因此 IT 就可以在路由器那裡設定一些規則,將某些網站給封住,進而讓你在上班時沒辦法瀏覽某些網站了。

所以比較一下正向代理和反向代理的話:

  • 正向代理(Forward Proxy): 將 Client 的資訊隱藏起來,由代理人統一的對外溝通。
  • 反向代理(Reverse Proxy): 相反過來,將 Server 的資訊隱藏起來,由代理人統一的對外溝通。

雖然大家在日常的後端開發中,很少會遇到正向代理的設定,但是多少了解一下正向代理的概念,仍舊是很有用的。

結語 #

這篇文章我們有詳細的去介紹了一下 Nginx 的用途,以及反向代理、負載平衡的概念是什麼,這些概念非常的重要,希望可以透過這篇文章,讓大家更了解 Nginx 這個工具實際要解決的問題是什麼。

如果你對後端技術有興趣的話,也歡迎免費訂閱 《古古的後端筆記》電子報 ,每週二為你送上一篇後端技術分享,那我們就下一篇文章見啦!

參考資料 #