Windows平臺分佈式架構實踐 - 負載均衡

概述

  最近.NET的世界開始鬧騰了,微軟官方終於加入到了對.NET跨平臺的支持,而且在不久的未來,咱們在VS裏面寫的代碼可能就能夠經過Mono直接在Linux和Mac上運行。那麼你們(開發者和企業)爲何那麼的迫切的但願.NET跨平臺呢?第一個理由是便宜,淘寶號稱4萬多臺服務器所有運行在Linux,Linux平臺下還有免費的MySql,這些都是免費的,這些省下來直接就是利潤呀,作企業的成本能夠下降又沒有任何損失,何樂而不爲呢?第二個理由是在Linux系統下還有不少很是優秀的構架(固然一樣也是免費的),分佈式緩存Memcached, 大數據處理構架Hadoop等等,這些都爲一些大型的分佈式系統提供了很好的支撐,固然還有諸如Liniux系統自己的一些安全和網絡方面的優點,等等。 因此也難怪大佬們都紛紛不約而同的沒有選擇.NET。 html

  可是若是.NET也支持跨平臺以後,那這樣的格局可能就要發生變化了。上面全部的優點依然能夠保留,而且加上它語法的優越性,以及快速的開發效率等,仍是會爲其爭得一席之地的。程序員

  可是,是否是Windows平臺下就不能實現這些大型的分佈式系統呢?我相信這個問題已經被普遍討論過,可是至少我沒有看到比較清晰的,完整的案例。帶着這些問題,我決定升級個人機器,本身從頭至尾在windows平臺下搭建一個高可擴展性的分佈式網站出來。我經驗尚淺,不少的東西還處於摸索階段,因此若是有錯誤,還請大師多多指點。web

什麼是負載均衡

  負載均衡能夠幫咱們解決兩個方面的問題,第一個即提升可用性。這裏面的可用性主要是從WEB服務器,的角度來說的,若是說咱們只有一臺Web服務器,而它遇到了某種未知的錯誤致使IIS沒法啓動,那麼咱們的網站就沒法訪問了,這就是一種比較低的可用性。那麼利用負載均衡,放在咱們Web服務器的前面,由它來收集全部的請求,而後轉發給咱們的Web服務器, 這時候咱們就能夠添加兩臺Web服務器,若是其中有一臺壞了,至少還有另外一臺在工做,也不至於致使咱們的網絡沒法訪問。數據庫

  

  固然,有人可能會問,若是那臺Load balancer壞了怎麼辦?那不是仍是訪問不了網站麼?咱們這裏討論的是提升可用性,在作到365天*24小時不間斷的服務,須要有另外的組件來支撐,咱們留在後面討論。除了可用性之外,負載均衡還能夠幫助咱們提升可擴展性,固然這個可擴展性一樣是指的Web服務器層面。從網站性能的角度來說,好幾個程序員花上好幾天的時間作了一些優化所帶來的效果有時候可能尚未直接加一根內存條來的快。內存加完了沒什麼影響,咱們還能夠換更好的CPU,CPU換完了,咱們還能夠用固態硬盤,甚至不少公司已經開始直接把數據放到內存中了(注:具體場景具體對待)。 若是這些都不能夠再加了呢?那就再加機器吧,一臺服務器能夠處理1000個併發,那麼兩臺理論上是2000了,因此這就有了咱們的橫向擴展。swift

  

負責均衡器分發請求的類型

  全部的請求首先所有到達Load balancer,再由它轉發到具體的Web服務器,轉發的方式分爲如下幾種:windows

  • 輪轉調度(Round-robin):最簡單的方式,這種方式基本上不能算是負載均衡。第一個請求給web1,下一個給web2,再下一個給web3... 不會考慮某 一個服務器是否是負荷過重等等。
  • 基於權重的分配(Weight-based): 能夠配置每一臺服務器處理請求數據的比例,特別適合那種有某臺服務器配置不同的場景。好比說某臺服務器配置特別好,那咱們可讓它多處理一些請求。
  • 隨機(Random): 隨機分配。
  • 粘性session(Sticky Session): Load balancer會跟蹤請求,確保同一個session id的請求都交給同同樣服務器。
  • 最空閒優先(Least current request)將最新的請求轉發給當前處理請求數量最小的那個服務器。
  • 響應時間優先(Response time):哪臺服務器當前響應時間最短就給哪臺。
  • 用戶或URL參數選擇(User or URL information)部分負載均衡器還提供根據一些參數來決定哪臺服務器來處理,好比說根據用戶信息,地址位置,URL參數,cookie信息等 。

  咱們還能夠根據負載均衡器所使用的技術將它們分爲如下幾類:緩存

  • 反向代理:負載均衡器做爲一個代理,同時維持着兩個TCP請求,從客戶端接收請求,而後將請求轉發給相應的Web 服務器,等Web返回Response的時候是返回給了代理服務器,而後再由代理服務器轉交給真正的客戶端。這樣就會致使有一些功能不可用,好比在WEB服務器環境查看請求的來源IP實際上成了咱們代理服務器的IP等。 
  • 透明反向代理:和上面的代理服務器同樣,只不過WEB服務器從Request中獲取到的信息是真正客戶端的信息,就是好像沒有使用代理同樣的。
  • 直接服務器返回:經過更改WEB服務器的MAC 地址來實現分發請求,在這種方式下,WEB服務器不會像上面使用代理服務器同樣,請求處理完以後是直接返回給客戶端的,全部相對於反向代理來講這種方式的性能會更快一些。 
  • NAT 負載均衡:NAT(Network Address Translation網絡地址轉換),將網絡包(能夠理解成TCP包)中的目標IP地址變成實現要處理這個請求的WEB服務器的地址。
  • Microsoft 網絡負載均衡:Windows 自帶的負載均衡組件,一會咱們就用它來作測試。 

不使用負載均衡的測試結果

一臺獨立的服務器

    咱們能夠從一個網站的最初級版本開始提及,最開始的時候咱們決定搭建一個網站,可是咱們也不知道效果會怎麼樣,光鍵是那時候,咱們很窮,因而咱們租用了一臺託管主機,它可能承擔了至少三個或以上的角色:WEB服務器、靜態資源服務器,以及數據庫服務器。咱們能夠用ASP.NET MVC4 + SQL 2008來作一個基本的電子商務網站,基本夠用了。可是可以承載多大的訪問量呢?下面咱們來作一個簡單的測試(注意:本文之後本系列所面全部的測試都是在虛擬機上進行的,忽略網絡的因素,以及多臺虛擬機同時運行時CPU資源的因素,因此測試結果只是一個參考)。安全

  在個人機器上有一臺虛擬機配置以下:服務器

  CPU: Intel Core I5- 4570, 3.19GHz,
  內存: 4G
  硬盤:20G (ShineDisk 固態硬盤)cookie

  測試頁面沒有什麼複雜的邏輯,利用ASP.NET MVC4 + Entityframework 6.0 + SQL 2008 + IIS8.5來實現, 咱們的頁面也只是一個簡單的列表頁,列出系統裏面全部的商品。

  Home Controller 代碼 
 

  Index.cshtml 代碼 
  

  在數據庫初始化的時候插入500條測試數據
  
  鏈接字符串就使用本地鏈接就能夠了。

1
2
3
<connectionStrings>
   <add name= "CarolContext"  connectionString= "Server=localhost;database=carol;trusted_connection=true"  providerName= "System.Data.SqlClient"  />
</connectionStrings>

  咱們使用的輕量級的ab來作壓力測試,若是不熟悉ab的能夠點這裏,下面是測試的結果:
  ab -n1000 -c100 http://192.168.1.131
  

  經過測試發現,咱們這單個服務器的吞吐率接近在110~130之間,而一旦併發數達到200之後,每一個請求的處理時間就達到1.5s多了,400個併發用戶的時候每一個請求要花上3s多的時間。若是在真實的網絡環境中可能會更差。由此咱們能夠得出咱們這個服務器可能最大支持120人左右同時訪問。 

WEB服務器與數據庫服務器分離

  如今咱們來作一個花費不是很大,又空間作的擴展,也不須要改任何架構,咱們只是再加一臺專門的數據庫服務器。

  

  下面咱們再來看一下測試結果:
  
  你們能夠看到,這裏咱們的吞吐率(每秒處理請求數已經提高到了150左右),併發處理能力提高了50%,而且300和400併發的時候響應時間也比上面的架構要好一些。 

使用負載均衡的測試結果

安裝網絡負載均衡(NLB)

  上面咱們一臺獨立的Web服務器和一臺獨立的數據庫服務器的組合已經能夠處理150左右的併發了,如今咱們假想一下若是網站的的知名度愈來愈大,若是同時有400個用戶來訪問怎麼辦? 從上面的圖中咱們能夠看到400個併發的時候服務器的處理時間爲2582.637ms(實現上這是拿到響應的時間,由於咱們是一臺機器上的不一樣虛擬機,我是在主機上作測試,因此咱們就忽略網絡傳輸的時間,假設這個就是咱們的服務器處理時間),這個服務器響應時間也就是咱們經過F12->網絡 中看到的等待時間 。

  頁面何時能拿到這個響應還要加上網絡傳輸的時間,也就是Receiving。1ms的傳輸時間堪稱神速啊!我家用的長城寬帶10M,老是早上網絡出奇的好,一到晚上就掛掉了,還有可能就是大家如今都沒有上博客園 :)

  用戶體驗黃金法則之一: 網站加載時間 = 用戶體驗,別說3S,可能等個2S你頁面還不出來,用戶準備離開了,下面是淘寶購物車頁面的加載時間 。

  國內不少大型的網站的響應時間基本上都控制在100ms之內,基本達到那種一輸入地址敲回車,眨眼之間頁面就出來了。固然這並非光有個負載均衡加幾臺web服務器就能解決的,咱們後來再來一步一步的實踐下去。 話說回來,咱們上面的測試結果基本上只有併發爲10的時候響應時間是在100ms之內的, 看來咱們還有很長的一段路要走啊。

  正所謂「最好的架構是進化而來的,而不是設計出來的」 ,面對咱們如今的瓶頸暫時經過負載均衡添加多臺Web服務器就能夠了。咱們上面講到負載均衡器類型的時候有一種 Microsoft負載均衡,咱們能夠很輕鬆的經過服務器管理器來將這些組件安裝到咱們的服務器中。 安裝咱們就不講了,就是經過服務器管理-> 添加角色和功能->在功能中選擇「網絡負載均衡」 而後安裝就能夠了。

  注意:圖中的Load balancer其實是不存在的,由於只要咱們2臺Web服務器安裝了網絡負載平衡組件,在其中任意一臺上創建羣集就能夠了,圖是爲了方便你們理解。 

  這樣的話咱們的服務器架構就成了下面這個樣子:
  
  192.168.1.254 就是咱們暴露的外部IP地址,訪問192.168.1.254的請求就會轉發給後面的兩臺WEB服務器。

配置網絡負載均衡

  在咱們爲上面2臺WEB服務器安裝NLB以後,咱們在其中任意一臺上來新建羣集,而後將另一臺加入到這個羣集中便可,咱們就在web-01(192.168.1.130)上來新建這個羣集。在創建羣集以前,咱們要確保這2臺服務器都是使用的靜態IP,不然沒法將他們加入到羣集中。

  • 在web-01(192.168.1.130)上從管理工具中打開 網絡負載均衡器
  • 右擊「網絡負載平衡羣集」,選擇「新建羣集」
  • 在「新羣集:鏈接」窗口中將 192.168.1.130添加爲主機,點擊下一步
  • 進入 「新羣集:主機參數」,直接下一步
  • 進入 「新羣集:羣集IP地址」, 添加窗口中的「添加」 將192.168.1.254 添加到窗口中而後點擊下一步

  • 進入 「新羣集:羣集參數」,選擇「多播」而後點擊下一步
  • 進入 「新羣集:端口規則」,選中所有,而後點擊編輯
  • 將端口範圍改爲 80~80,協議選 「TCP」,相關性選「無」
  • 點擊肯定回到主窗口,而後點擊完成。
  • 經過上面的步驟,咱們已經創建了一個羣集,而且將web-01加入到了羣集中,咱們還須要手動將web-02也加入到羣集中。


  • 在羣集(192.168.1.254)上右鍵點擊「添加主機到羣集」
  • 在「將主機添加到羣集:鏈接」窗口中的 主機中輸入192.168.1.131而後後面一下點下一步便可。

  如今咱們就能夠到咱們的真實機器上去訪問192.168.1.254了,也就是說立刻咱們就進入測試環節了。

測試結果

  本文中全部的測試結果都沒有取第一次的結果,EF也須要預熱,一樣的查詢在EF中也是有緩存的,因此第一次的結果會與後面的測試結果有很大的區別,後面的幾回(在相同參數下)基本差異就不大了。
  

  能夠看到如今咱們的吞吐率大概平均在230左右,與一臺WEB服務器+一臺DB服務器相比,處理能力又提升了50%,爲何不是100%呢?一臺WEB服務器能處理150的併發,那兩臺應該是300纔對呀?我可以想到如下緣由:

  1. 咱們的數據庫服務器只有一臺,數據庫的處理能力提不上去最終影響WEB服務器的處理能力
  2. 咱們採用的是虛擬機,並不是實際的機器,他們其實是共用CPU,不知道在這種狀況下對測試結果會不會有影響(虛擬化專家能夠分享一下)。

  爲了驗證一下,我再擴展了一臺WEB服務器,咱們使用3臺WEB服務器+1臺DB服務器看看是什麼效果。
  
  咱們新建一臺虛擬機web-03,而後將它也加入到咱們的羣集中。
  

   測試開始! 
  
   在加入第三臺WEB服務器以後,咱們的吞吐率(每秒處理請求數)再次獲得提高從230升至360,併發處理能力再次提高56%,而且你們能夠看到,400併發如下的平均每請求處理時間都在1s之內,可喜可賀啊!
   最後上兩圖讓你們更直觀的看一下這些性能的變化:

  
  

  以上數據均來自本人機器上的測試,虛擬機所有采用與第一臺服務器一樣的配置。

小結

  在網站架構的不斷演變中,負載均衡起着很是重要的位置,不只僅爲咱們提高可靠性和可擴展性,有一些比較強大的硬件設備還能提供緩存,以及session機制。今天咱們用到的負載均衡是Windows Server自帶的一個組件,它是最簡單實現負載均衡的方式,可是功能不是特別完善,並且一旦NLB自己發生錯誤那麼將致使全部的網站都不能訪問,咱們後面就來經過引入APR(Application Request Router)來解決這個問題,想要真正瞭解大型網站的架構實現,而不是僅僅知道負載均衡,分佈式緩存,數據庫分離這些名詞麼?那就來跟我一塊兒學習吧!另外咱們今天只是用一個簡單的頁面作了壓力測試,只有讀數據的操做,尚未寫的操做,也沒有任何複雜的事務,可是別擔憂,咱們一步一步來 :) 。

  您還能夠查看本篇的續篇: Windows平臺下利用APM來作負載均衡方案 - 解決Session同步問題,以及完全提升可用性。

做者:Jesse  原文地址:http://www.cnblogs.com/jesse2013/p/dlws-loadbalancer.html

相關文章
相關標籤/搜索