當我們的網站PV值達到很大時,單機部署已經頂不住併發的訪問量,這時通常需要部署多個站點做負載均衡。IIS實現負載均衡比較常用的方式是Server Farms/NLB/Nginx,其中Server Farms和NLB比較簡單無腦,安裝好程序,通過可視化界面配置Server站點以及負載均衡的策略即可。我們來看一下更輕量化的實現方式,通過Nginx反向代理。
Nginx安裝配置
前往Nginx官網下載Nginx安裝,下載後解壓運行nginx.exe,然後訪問localhost,如出現下面畫面證明Nginx正常無問題:
注意80端口可能被IIS佔用了,運行Nginx前需要先將IIS80端口網站停掉,或者修改nginx配置文件改爲其它端口再運行
網站準備
這裏我們寫一個簡單的網站,作爲需要負載均衡訪問的站點,並且在IIS上部署三個站點模擬三臺服務器。
<%@ Page Title="主頁" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebTest._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
歡迎使用 ASP.NET!
<h3>
服務器地址:<%= Request.ServerVariables.Get("Server_Name").ToString()%></h3>
<h3>
服務器端口:<%= Request.ServerVariables.Get("Server_Port").ToString()%>
</h3>
</h2>
<p>
若要了解關於 ASP.NET 的詳細信息,請訪問 <a href="http://www.asp.net/cn" title="ASP.NET 網站">www.asp.net/cn</a>。
</p>
<p>
您還可以找到 <a href="http://go.microsoft.com/fwlink/?LinkID=152368" title="MSDN ASP.NET 文檔">
MSDN 上有關 ASP.NET 的文檔</a>。
</p>
</asp:Content>
網站代碼比較簡單,就是在網頁上顯示當前服務器的地址及端口,然後在IIS上新建三個站點指向這個網頁,端口分別爲8010,8020,8030,如下:
分別訪問這三個站點結果如下:
配置Nginx代理
修改nginx.config配置文件如下:
#添加集羣,名稱爲jq_test
upstream jq_test{
server 127.0.0.1:8010; #將服務器地址添加到集羣中
server 127.0.0.1:8020;
server 127.0.0.1:8030;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm Default.aspx; #修改主頁爲我們站點上的Default.aspx
proxy_pass http://jq_test;
}
然後切換到nginx目錄下運行命令nginx -s reload重啓nginx服務,然後我們重新訪問localhost地址,發現已經指向了我們部署的三個IIS站點,如下:
可以看到Nginx已經把對80端口的訪問轉發到了我們部署的IIS站點上,並且我們不停刷新發現,每次轉發後頁面上顯示的服務器端口都在變化,說明轉發到了不同的站點上。至此,Nginx+IIS實現負載均衡已經初步實現。
後續問題優化
在實現負載均衡後,我們就需要面臨由單機應用轉變爲分佈式應用需要面對的問題:
1. 如果我們的站點使用了session,現在請求被負載均分到多個站點了,那麼這多個站點間如何共享session?
分佈式應用常用的session共享方式是數據庫或者Redis存儲,讀寫session都從同一個數據庫或Redis操作,在後面的博文中我們會講述通過redis實現session的共享。
2. 如果多臺服務器的配置不同,希望將更多的請求分到配置更高的服務器如何實現?
nginx可以通過加權法來控制請求的分配比例,通過nginx.config配置如下:
upstream Jq_test{
server 127.0.0.1:8082 weight=4;
server 127.0.0.1:9000 weight=1;
}
其中,weight值就是權重,權重越大,相應的分配到的請求越多。負載均衡還有很多策略,Server Farms/NLB 這兩種負載實現方式有更多經典策略的實現,大家可以自己嘗試下。
3. 在做了負載均衡後,每次站點有更新需要同步到所有站點,假如負載的站點總共有10個,那麼需要將更新包更新到10臺服務器上,耗時且容易出錯遺漏。
多服務器站點更新可以使用GoodSync 文件同步程序,會自動檢測文件的修改新增,然後同步到其它服務器上。在linux下可以使用rsync
4. 在某些場景比如限量秒殺時,我們會對下單等業務代碼做加鎖控制,如果是單機部署,我們只需要通過lock就能保證最終秒殺數在控制內,但是在分佈式部署後,lock不能保證其它服務器上的進程受控制因此失效
解決這個問題就需要增加針對分佈式系統的鎖設計,常見的實現方式就是通過Redis和Zookeeper來做一個控制中心,嘗試佔用鎖和解鎖都統一通過這個控制中心。後面的博文中再詳細講解如何實現。
下一篇:分佈式之Session共享