[轉]反向代理過程與Nginx特點詳解

Jelly_lyj發表於2017-03-18

原文連結:<Nginx搭建反向代理伺服器過程詳解>

反向代理

1.1 反向代理初印象

反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個伺服器

Nginx搭建反向代理伺服器過程詳解

從上圖可以看出:反向代理伺服器位於網站機房,代理網站Web伺服器接收Http請求,對請求進行轉發。

1.2 反向代理的作用

保護網站安全:任何來自Internet的請求都必須先經過代理伺服器;

Nginx搭建反向代理伺服器過程詳解

通過配置快取功能加速Web請求:可以快取真實Web伺服器上的某些靜態資源,減輕真實Web伺服器的負載壓力;

Nginx搭建反向代理伺服器過程詳解

實現負載均衡:充當負載均衡伺服器均衡地分發請求,平衡叢集中各個伺服器的負載壓力;

Nginx搭建反向代理伺服器過程詳解

初識Nginx:簡單卻不平凡

2.1 Nginx是神馬?

Nginx搭建反向代理伺服器過程詳解

Nginx是一款輕量級的網頁伺服器、反向代理器以及電子郵件代理伺服器。其將原始碼以類BSD許可證的形式釋出,因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。

Source:Nginx(發音同engine x),它是由俄羅斯程式設計師Igor Sysoev所開發的。起初是供俄國大型的入口網站及搜尋引擎Rambler(俄語:Рамблер)使用。此軟體BSD-like協議下發行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及Microsoft Windows等作業系統中執行。

說到Web伺服器,Apache伺服器和IIS伺服器是兩大巨頭;但是執行速度更快、更靈活的對手:Nginx 正在迎頭趕上。

2.2 Nginx的應用現狀

Nginx 已經在俄羅斯最大的入口網站── Rambler Mediawww.rambler.ru)上執行了3年時間,同時俄羅斯超過20%的虛擬主機平臺採用Nginx作為反向代理伺服器。

Nginx搭建反向代理伺服器過程詳解Nginx搭建反向代理伺服器過程詳解Nginx搭建反向代理伺服器過程詳解Nginx搭建反向代理伺服器過程詳解Nginx搭建反向代理伺服器過程詳解

在國內,已經有 淘寶、新浪部落格、新浪播客、網易新聞、六間房、56.com、Discuz!、水木社群、豆瓣、YUPOO、海內、迅雷線上 等多家網站使用 Nginx 作為Web伺服器或反向代理伺服器。

2.3 Nginx的核心特點

(1)跨平臺:Nginx 可以在大多數 Unix like OS編譯執行,而且也有Windows的移植版本;

(2)配置異常簡單:非常容易上手。配置風格跟程式開發一樣,神一般的配置;

(3)非阻塞、高併發連線:資料複製時,磁碟I/O的第一階段是非阻塞的。官方測試能夠支撐5萬併發連線,在實際生產環境中跑到2~3萬併發連線數。(這得益於Nginx使用了最新的epoll模型);

PS:對於一個Web伺服器來說,首先看一個請求的基本過程:建立連線—接收資料—傳送資料,在系統底層看來 :上述過程(建立連線—接收資料—傳送資料)在系統底層就是讀寫事件

①如果採用阻塞呼叫的方式,當讀寫事件沒有準備好時,必然不能夠進行讀寫事件,那麼久只好等待,等事件準備好了,才能進行讀寫事件,那麼請求就會被耽擱 。

②既然沒有準備好阻塞呼叫不行,那麼採用非阻塞呼叫方式。非阻塞就是:事件馬上返回,告訴你事件還沒準備好呢,你慌什麼,過會再來吧。好吧,你過一會,再來檢查一下事件,直到事件準備好了為止,在這期間,你就可以先去做其它事情,然後再來看看事件好了沒。雖然不阻塞了,但你得不時地過來檢查一下事件的狀態,你可以做更多的事情了,但帶來的開銷也是不小的。

(4)事件驅動:通訊機制採用epoll模型,支援更大的併發連線。

①非阻塞通過不斷檢查事件的狀態來判斷是否進行讀寫操作,這樣帶來的開銷很大,因此就有了非同步非阻塞的事件處理機制。這種機制讓你可以同時監控多個事件,呼叫他們是阻塞的,但可以設定超時時間,在超時時間之內,如果有事件準備好了,就返回。這種機制解決了上面阻塞呼叫與非阻塞呼叫的兩個問題。

②以epoll模型為例:當事件沒有準備好時,就放入epoll(佇列)裡面。如果有事件準備好了,那麼就去處 理;如果事件返回的是EAGAIN,那麼繼續將其放入epoll裡面。從而,只要有事件準備好了,我們就去處理它,只有當所有事件都沒有準備好時,才在 epoll裡面等著。這樣,我們就可以併發處理大量的併發了,當然,這裡的併發請求,是指未處理完的請求,執行緒只有一個,所以同時能處理的請求當然只有一 個了,只是在請求間進行不斷地切換而已,切換也是因為非同步事件未準備好,而主動讓出的。這裡的切換是沒有任何代價,你可以理解為迴圈處理多個準備好的事 件,事實上就是這樣的。

③與多執行緒方式相比,這種事件處理方式是有很大的優勢的,不需要建立執行緒,每個請求佔用的記憶體也很少,沒有上下文切換, 事件處理非常的輕量級,併發數再多也不會導致無謂的資源浪費(上下文切換)。對於IIS伺服器,每個請求會獨佔一個工作執行緒,當併發數上到幾千時,就同時 有幾千的執行緒在處理請求了。這對作業系統來說,是個不小的挑戰:因為執行緒帶來的記憶體佔用非常大,執行緒的上下文切換帶來的cpu開銷很大,自然效能就上不 去,從而導致在高併發場景下效能下降嚴重。

總結:通過非同步非阻塞的事件處理機制,Nginx實現由程式迴圈處理多個準備好的事件,從而實現高併發和輕量級

(5)Master/Worker結構:一個master程式,生成一個或多個worker程式。

Nginx搭建反向代理伺服器過程詳解

PS:Master-Worker設計模式核心思想是將原來序列的邏輯並行化, 並將邏輯拆分成很多獨立模組並行執行。其中主要包含兩個主要元件Master和Worker,Master主要將邏輯進行拆分,拆分為互相獨立的部分,同 時維護了Worker佇列,將每個獨立部分下發到多個Worker並行執行,Worker主要進行實際邏輯計算,並將結果返回給Master。

問:nginx採用這種程式模型有什麼好處?

答:採用獨立的程式,可以讓互相之間不會影響,一個程式退出後,其它程式還在工作,服務不會中斷,Master 程式則很快重新啟動新的Worker程式。當然,Worker程式的異常退出,肯定是程式有bug了,異常退出,會導致當前Worker上的所有請求失 敗,不過不會影響到所有請求,所以降低了風險。

(6)記憶體消耗小:處理大併發的請求記憶體消耗非常小。在3萬併發連線下,開啟的10個Nginx 程式才消耗150M記憶體(15M*10=150M)。

(7)內建的健康檢查功能:如果 Nginx 代理的後端的某臺 Web 伺服器當機了,不會影響前端訪問。

(8)節省頻寬:支援 GZIP 壓縮,可以新增瀏覽器本地快取的 Header 頭。

(9)穩定性高:用於反向代理,當機的概率微乎其微。

 


 

理解網路IO之阻塞、非阻塞、同步、非同步

原文連結:<網路IO之阻塞、非阻塞、同步、非同步總結>

1、前言

  在網路程式設計中,阻塞、非阻塞、同步、非同步經常被提到。unix網路程式設計第一卷第六章專門討論五種不同的IO模型,Stevens講的非常詳細,我記得去年看第一遍時候,似懂非懂,沒有深入理解。網上有詳細的分析:http://blog.csdn.net/historyasamirror/article/details/5778378。我結合網上部落格和書總結一下,加以區別,加深理解。

2、資料流向

  網路IO操作實際過程涉及到核心和呼叫這個IO操作的程式。以read為例,read的具體操作分為以下兩個部分:

  (1)核心等待資料可讀

  (2)將核心讀到的資料拷貝到程式

詳細過程如下圖所示:

3、網路IO模型詳細分析

  常見的IO模型有阻塞、非阻塞、IO多路複用,非同步。以一個生動形象的例子來說明這四個概念。週末我和女友去逛街,中午餓了,我們準備去吃飯。週末人多,吃飯需要排隊,我和女友有以下幾種方案:

  (1)我和女友點完餐後,不知道什麼時候能做好,只好坐在餐廳裡面等,直到做好,然後吃完才離開。

女友本想還和我一起逛街的,但是不知道飯能什麼時候做好,只好和我一起在餐廳等,而不能去逛街,直到吃完飯才能去逛街,中間等待做飯的時間浪費掉了。這就是典型的阻塞。網路中IO阻塞如下圖所示:

  (2)我女友不甘心白白在這等,又想去逛商場,又擔心飯好了。所以我們逛一會,回來詢問服務員飯好了沒有,來來回回好多次,飯都還沒吃都快累死了啦。這就是非阻塞。需要不斷的詢問,是否準備好了。網路IO非阻塞如下圖所示:

  (3)與第二個方案差不多,餐廳安裝了電子螢幕用來顯示點餐的狀態,這樣我和女友逛街一會,回來就不用去詢問服務員了,直接看電子螢幕就可以 了。這樣每個人的餐是否好了,都直接看電子螢幕就可以了,這就是典型的IO多路複用,如select、poll、epoll。網路IO具體模型如下圖所 示:

  (4)女友不想逛街,又餐廳太吵了,回家好好休息一下。於是我們叫外賣,打個電話點餐,然後我和女友可以在家好好休息一下,飯好了送貨員送到家 裡來。這就是典型的非同步,只需要打個電話說一下,然後可以做自己的事情,飯好了就送來了。linux提供了AIO庫函式實現非同步,但是用的很少。目前有很 多開源的非同步IO庫,例如libevent、libev、libuv。非同步過程如下圖所示:

4、同步與非同步

  實際上同步與非同步是針對應用程式與核心的互動而言的。同步過程中程式觸發IO操作並等待或者輪詢的去檢視IO操作是否完成。非同步過程中程式觸發IO操作以後,直接返回,做自己的事情,IO交給核心來處理,完成後核心通知程式IO完成。同步與非同步如下圖所示:

5、阻塞與非阻塞

  簡單理解為需要做一件事能不能立即得到返回應答,如果不能立即獲得返回,需要等待,那就阻塞了,否則就可以理解為非阻塞。詳細區別如下圖所示:

 

相關文章