概述
我們在上一篇Windows平台分布式架構實踐 - 負載均衡中討論了Windows平台下通過NLB(Network Load Balancer) 來實現網站的負載均衡,並且通過壓力測試演示了它的效果,可以說還是非常的理想的。同時我們也收集到了不少的問題,比如說如何在這種分布式的架構下使用Session,NLB中有一台服務器掛掉了會導致對外暴露的地址無法訪問,如果實現服務器之間的同步,如果更好的進行熱修復等等,還有我們在上一篇中也提到了NLB所提供的功能是非常簡單的,為了回答我們前面提到的問題,也為了提供一個比較全面完整的負載均衡方案,我們來看看Windows平台下負載均衡的另一種實現APR (Application Request Router + Web Farm + Url Rewriter),希望可以為大家解決一些實現的問題。
目錄
安裝配置負載均衡
安裝相關組件
話不多說,為了實現一個比較完整的負載均衡,我們要引入以下5個組件。
- Web Deploy V3.0
- Web Platform installer V5.0
- Web Fram 2 for IIS7
- Applicaiton Request Router 3 for IIS
- Url Rewriter 2 for IIS7
安裝Web Fram 必須要先安裝Web Deploy 和Web Platform,所以我把它們倆放在最前面,你也可以參考上面的順序來安裝,當然你首先得自己把IIS和ASP.NET 模塊給裝上。我們這次不會對這5個組件的原理做詳細的介紹,大家知道怎么操作就可以了,如果有興趣的同學可以繼續深入。安裝過程非常的簡單,基本上每一個組件只需要點一下按鈕就可以了,全部安裝完之后,你就會在當前那台機器上的IIS下看到一個Server Farms的結點。
配置負載均衡
如果大家還有印象,在使用NLB配置負載均衡的時候,我們是不需要一台單獨的機器來作為主入口的。 我們給所有的WEB服務器都安裝上NLB,然后選擇任意一台將其它的WEB服務器加進入同時設置一個單獨的IP作為入口地址即可。 但是換成APR,情況就有點不一樣了。我們需要一台單獨的入口服務器來接收所有的請求,由它再把所有的請求根據配置的規則轉發給其它真實的WEB服務器。
3 台Web 服務器我們還是用我們上次做過實驗的那三台,我們再添加一台配置一樣的虛擬機,然后給這4台服務器全部安裝上APR(包括我們上面列出的5個組件)之后,我們就可以開始配置了。我們首先在我們的入口服務器上創建一個Web Farm。在IIS中右擊Server Farms -> Create Server Farm,
我們勾上“Server farm is available for load balancing(在Web Fram中使用負載均衡)” ,下面的“Provision server farm”,我們也勾上,並為它輸入一個賬戶,這個賬戶要求有權限可以訪問這個Web Farm里面的所有服務器。Provision 主要是用來實現主-從服務器同步的,我們暫時先忽略它,后面再具體講。
我們將192.168.1.130設置我們的主Web 服務器,一會我們結合Provision(俺不知道這個翻成中文該叫什么,直譯“提供”好像很別扭) 功能就可以實現在主服務器上部署和更改配置就會被自動同步到其它的服務器上。完成創建Web Farm之后,我們就可以在IIS中進行后面的配置了。我們通過點擊每一個Web Farm下的Servers來查看每一個Web服務器的狀態,是不是連接正常等等 。
同時我們還可以點擊每一個Web farm來進行以下功能的管理,這里我們就點擊Mono。
配置Load Balance 算法
我們首先要做的就是進入 “Load Balance”,在這里你可以選擇負載均衡的算法 :輪轉調度,隨機分配,URL參數,請求頭等。如果不了解這些算法干什么 的,那就去復習上一篇吧。APR為我們提供了以下7種算法:
- Weighted round robin 根據權重按照請求數據進行分配
- Weighted total traffic 根據權重按照請求和響應字節大小進行分配
- Least current request 優先轉發給那個當前處理最少請求的服務器
- Least response time 優先轉發給那個當前響應最快的服務器
- Server variable hash 根據服務器變量的hash來分配請求,這里面的服務器變量包括Cookie, URL,頭信息等 ,詳情點這里。
- Query string hash 根據URL查詢字符串的hash來分配請求,如果查詢字符串包含多個參數(?name=jesse&location=sh),則是用整個查詢字符串的hash來作判斷。
- Request hash 根據服務器變量或者是URL的hash來分配請求,比如說服務器變量是QUERY_STRING,那么hash的值就是query string中對應的那個值。
大家可以已經猜到,后面3種算法是可以利用來實現這種分布式環境下session的訪問的,但是由於要涉及到其它的配置,所以我們后面再講,讓我們先專注於把這個負載均衡配置完,所以我們就里就先選擇比較簡單的Least response time,誰當前返回響應最快我們就把請求給它,驗證了那句話,“能者多勞啊”。
配置轉發規則
APR的機制是做為一個代理服務器,它負責接收請求,但是不做任何處理,而是直接將請求分發給具體的WEB服務器。同時我們還可以配置一些規則,有一些請求轉發,有一些請求不轉發,這就要感謝我們的url rewrite組件了。我們可以進入“Routing Rules”來進行相關的配置。
網站部署與同步
安裝程序和運行環境同步
在實際的環境中,如果我們使用NLB在第一次部署的時候,就需要一個服務器一個服務器的部署,而且如果要對IIS進行其它的一些配置就會顯得很煩瑣。在APR中給我們提供的Provision功能,就可以幫助實現這樣的同步功能。
在Server Farm的功能視圖中,我們可以找到以下兩種類型的Provision:
- Application Provisioning: 主要是用來同步網站相關包括內容,配置等等,Web Deploy就是用在這里了。
- Platform Provisioning:主要是用來同步安裝程序的,其實這里面的Platform是指我們上面安裝的 Web Platform Installer,也就是說我們在主服務器上通過Web Platform安裝的程序或者組件,如果啟用了Platform Provisioning的話,其它所有的服務器也會自動安裝上。
我們可以來做一個Platform Provisioning的例子,點擊我們的Server Farm -> 在右邊的功能視圖中雙擊Platform Provisioning -> 勾選下面兩個選項。
然后我們點擊左右的Servers,選中我們的主服務器(Primary),在右邊的操作列表中選擇 “Install Product”,在彈出的窗體中安裝的程序就會被自動安裝到當前Server Farm中的所有其它服務器中。
網站內容同步
和上面的思路一樣,我們不需要每一個程序都部署一遍,我們只需要在主服務器上部署一遍就可以了,所有的內容以及IIS的設置都會被自動同步到其它服務器上,這就是Application Provisioning來幫我們實現的。我們可以通過點擊我們的Server Farm ->在右邊的功能視圖中雙擊 “Applicaiton Provisioning” 然后勾選下面的兩項即可。
接下來,我們只需要在我們的主服務器上建立我們的站點然后部署我們的網站即可,包括對網站進行一些應用程序池的配置也是只需要在主服務器上完成的,我們就不需要到每一台服務器上都去布置一遍了。
配置入口服務器
既然入口服務器不做任何處理只是轉發請求的話,那我們還需要把我們的網站的內容放在入口服務器的IIS下么?這個就取決於不同的場景了,你可以建一個空的站點什么也沒有,你也可以用它來做一個簡單的文件服務器,在上一步中將靜態文件不轉發即可,讓我們Web Farm中的服務器只處理動態的請求,也可以減輕他們的壓力。當然如果你有單獨的文件服務器那就更好了。作為測試用途我們在入口服務器上就不建任何網站了,直接使用安裝IIS自帶的那個默認網站即可。
有人可能會有疑問,因為我在配置Server Farm的時候同樣也有這樣的一個疑問。“所有的請求都是由入口服務器接收,然后再分發給Farm中具體的服務器的,那入口服務器的那個網站該如何配置呢? 是用80還是8080端口,如果我建了好幾個網站,那到底哪一個網站的請求會被Farm拿到再進行轉發呢?”
我在入口服務器中沒有做任何網站的配置,也就是說本地有一個http://localhost的網站是可以訪問的,對於外部來說它的地址就是 http://192.168.1.129/,那么為什么當外部訪問 192.168.1.129的時候,它就會被Farm 中的服務器處理呢? 這就要多虧我們的Url Rewrite模塊了,我們可以點擊我們的Farm Mono,進入到功能視圖->然后點擊 Routing Rules -> 在Routing Rules 右側的操作列表中點擊 URL Rewrite... 對Routing Rules進行更詳細的管理。
在我們的URL Rewrite窗口,我們就會看到已經為我們默認創建了一條入站的規則。
我們可以雙擊那條規則查看詳細,或者進行編輯,我們可以看到這條規則實際上是用通配符匹配了所有的入站請求,然后轉發給我們的Server Farm: Mono。原來是URL Rewrite在這里起了作用,當然我們也可能把 *改成 其它的通配符,以及使用正則表達式來匹配都是可以的,這些都是URL Rewite里面的功能,是可以直接搬過來用的。
URL Rewrite幫助我們匹配入站請求,然后轉發給Farm,在Farm層面 APR根據 我們配置的負載均衡算法將請求轉發給具體的服務器去處理請求。現在我們再回過頭來看看我們最開始安裝的5個組件都分別起到了什么作用。
- Web Deploy : 參與Application Provisioning(網站內容及配置同步)
- Web Platform Installer: 參與Platform Provisioning( 應用環境同步)
- Web Farm: 主要組織者及容器
- Application Request Router: 負載均衡處理
- URL Rewrite: 入站請求匹配等
驗證負載均衡
到這里為止,我們用 APR + Web Farm搭建的負載均衡就完成了,最終結果是我們在外面訪問 http://192.168.1.129的時候,實際上是由我們Farm中的3台Web 服務器處理的,口說無憑,我們來驗證一下。驗證的方法很簡單,我們在每個服務器下放不同的文件用來標識當前是哪個服務器在處理響應(記得在部署文件的時候要先把Application provisioning關閉掉,不然主服務器上的文件會被同步到其它的服務器上去的)。
在web-02和 web-03上,分別返回不前的服務器的名字就可以了。但是在測試上可能會遇到一點小問題,那就是當我們訪問http://192.168.1.129的時候,總是由web-01處理的,因為我們的頁面幫簡單,又只有一個用戶在訪問,所有后面兩台服務器壓根沒有發揮作用。這時候我們就可以把web-01和 web-02從 Farm中移除掉,那么所有的請求就會被web-01來處理了。
就是這么簡單,Web Farm給我們提供的這個功能非常的實用,我們可以在運行時隨時動態的添加或移除服務器。還記得以前我們只有一台服務器的時候,為了盡可能的不影響用戶,發布都選擇在晚上的10點以后,所以經常是一發布就通宵。想想如果有這個功能,白天也可以發布了,只要先把一些機器從Web Farm中拿下來,發布好測試通過之后再放上去並且把別外那一些也拿下來發布就好了。當然這種場景只適合一些中小型的網站,一旦網站大了,那發布將會是一個非常嚴格的流程,而且一般會有專門的發布人員或者工具。
Session在APR 分布式環境下的應用
關於Session在分布式環境下的使用其實是有爭議的,有人說老師都不讓用Session了,但是有人又想方設法的想要使用它。我們暫且不討論它的正確與否,因為沒有最好的架構,只有最合適的架構,正所謂存在即合理。我們都不得不承認Session在很多管理系統,以及一些小型的網站的開發上帶來了很大的便利性,開發快速同時又可以帶來看得見的性能提升。所有個人認為,用還是不用那就看場景吧。但是我們從學習的角度出發,還是應該考慮到各種可行性,以及他們之間的利與弊,這樣才能幫助我們在真實情況下做出最合適的決策。
Server Affinity(服務器關聯性)
在Farm的功能視圖中,有一個Server Affinity的功能可以用來跟蹤請求或者說提供一種服務器和客戶端之間的粘性,當第一個請求被處理之后,這個請求所在客戶端后面發起的所有請求都會交給同樣的服務器來處理,這就是Server Affinity。APR為我們提供了兩種選項:
- Client Affinity: 會給來自不同客戶端的請求分配一個cookie,然后根據這個cookie來識別請求應該由哪個服務器來處理。
- Host Name Affinity:根據Host name來作粘性處理,它還有兩種provider可以采用:
- Microsoft.Web.Arr.HostNameRoundRobin: 保證盡量平均分配到服務器
- Microsoft.Web.Arr.HostNameMemory: 根據內存使用情況來分配,保證各個服務器的內存使用情況達到均衡。
原來在APR這種分布式架構下使用Session是這么的簡單,而且我們可以根據實際情況,Client Affinitt 和 Host Name Affinity一起使用。
搭建多台APR服務器來提升可靠性
還記得我們在上一篇中提到的,引入負載均衡幫提高了兩點:可靠性和可擴展性。多台服務器共同處理的情況下,哪怕其中部分出了問題也不會導致整個網站無法訪問,提高了我們的可靠性。隨時動態的添加和移除服務器而不影響網站的訪問,提供了我們的可擴展性。但是這里還有一個問題,但是如果APR所在的那個服務器出了問題怎么辦?雖然這種可能性比較低,因為我們的APR服務器只是做了很簡單的轉發請求的功能,並沒有運行真實的網站,但仍然不排隊會有其它的異常導致IIS或者Web Farm停止運行,對於像這樣的問題,我們就可以通過部署多台APR服務器來再一次提升我們網站的可靠性。
一台APR服務器可以將請求分發給具體的服務器,如果是多台APR服務器,那誰來決定請求是由哪台APR服務器處理呢?
還記得我們上篇講的NLB么?它不需要一台單獨的服務器配置,只需要給目標機器都裝上NLB,然后配置一個暴露給外部的地址就可以了。所以這次當我們訪問外部地址的時候會有接下來的幾步動作:
- NLB最先拿到請求信息,然后具體的APR服務器再去響應請求
- 當某台APR響應請求的時候會根據配置好的負載均衡算法交給后面具體的Web服務器去處理
- Web服務器請求完之后,再把響應信息返回給客戶端