ASP.NET網站中做負載平衡:
基於HTTP協議我們可能發現我們要解決兩點問題:
第一,做到負載平衡,我們需要一個負載平衡器。
可以通過DNS輪詢來做,在DNS伺服器上配置為每次對我們做負載平衡的同一主機名稱的DNS查詢得到不同的IP地址。這樣的好處是配置簡單投入較小,缺點是瀏覽器訪問各個伺服器的機會是均等的,不能根據伺服器的負載程度自動把請求路由到負載較小的伺服器。
可以通過專用的負載平衡裝置,通過監測後台數台伺服器的負載情況,自動把HTTP請求轉寄到負載較輕的伺服器。另外必須監測後台伺服器的IIS負載情況,而不是整台伺服器的CPU負載。同時可能需要在負載平衡器和後台服務應用之間建立心跳串連,以避免出現某台伺服器IIS進程或者其中跑的應用已經down掉,負載平衡器反而監測到這台伺服器的負載最小而把大量請求轉寄的這台伺服器,達到相反的效果。
第二,Session狀態的保持和遷移。
由於HTTP協議的無狀態性,我們一般是在Session中儲存用戶端的一些狀態資料,負載平衡之後,前後兩次HTTP請求所到達的伺服器可能不是同一台,這就造成可能出現這樣的情況,前一此請求處理中設定的session在第二次請求中變得不可用了,造成應用程式出錯。所以我們要把session跟隨遷移。實現的方法就是session的統一儲存和伺服器間共用。
在ASP.NET中伺服器儲存session有五種方式,Off不說了,InProc是儲存在伺服器處理序的記憶體中,顯然不能滿足要求。另外兩種能夠滿足:
StateServer是把session儲存在專門的狀態伺服器中。這樣各台伺服器都存取同一個StateServer,達到共用的目的。
SQLServer是把session儲存在資料庫中。同樣能達到目的。
Custom自定製的儲存方案,我們自己寫當然能夠實現。
比較一下,Custom這種自己實現比較麻煩一般不用,SQLServer可以利用資料庫的cluster達到高效能和高可用性的目的,StateServer當然也可以通過手段達到高可用性,不過似乎不能實現叢集所以效能也有所限制。
另外如果要做負載平衡在StateServer和SQLServer中配置session時,必須在web.config中重寫machineKey節點:
<machineKey
validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"
decryptionKey="123456789012345678901234567890123456789012345678"
validation="SHA1"
decryption="Auto"
/>
否則各個應用伺服器拿到的session還是不一樣的。
可能Custom方式可以自己定義存取session方式忽略machineKey,這可能就不必要了,因為沒有做過,不多說。