Web開發系列(八):單點故障,負載均衡
試想我們有一個內容伺服器,假設是監聽在192.168.1.1:8000
上,我們所有的請求都打到這上面,那麼這個程序或者機器掛了怎麼辦?
因此有一個新的概念,叫做ofollow,noindex" target="_blank">單點故障 。即,只要我們這唯一的,僅有的 內容伺服器掛了,我們的網站就掛了。所以我們需要一個新的概念,叫做負載均衡 。
當然,負載均衡的目的遠不止是這一個,包括但不限於:冗餘,降低響應時間,降低內容伺服器負載,健康檢查等。
在現實生產環境中,對HTTP或HTTPS請求而言,我們一般使用nginx來做負載均衡,即使用例如這樣的配置:
upstream backend { server backend1.example.comweight=5; server backend2.example.com:8080; server unix:/tmp/backend3; server backup1.example.com:8080backup; server backup2.example.com:8080backup; } server { location / { proxy_pass http://backend; } }
而Nginx的負載均衡有以下幾種演算法:
- round-robin 幾乎是個負載均衡器都支援,即,一個一個輪著來
- least-connected 找活躍連線數最少的進行請求
- ip-hash 根據ip地址進行雜湊,然後分配到對應的內容伺服器上
這三種演算法各有千秋,第一種足夠公平,大家都有份(當然也可以配置權重和backup),第二種能比較好的均衡負載,第三種則能 保證只要是同一個使用者的請求,一定會到同一臺伺服器上,比較適用於這樣一種情況:每臺內容伺服器連線一個私有的Redis,Redis中 儲存了session,如果用第一種或者第二種演算法,那麼使用者會出現隨機要求重新登入的情況,第三種則不會。
但是,我們引入了Nginx作為內容伺服器的負載均衡,同時Nginx自身也成為了新的單點故障,即,只要Nginx掛了,網站也就掛了。 那麼,有沒有什麼好辦法呢?有!
- 其一,我們可以用上篇 提到的,利用DNS做 負載均衡,這樣不同的地方的使用者訪問到不同的伺服器上,但是這在實際開發中比較困難,例如,如果有資料存放在Redis中,多個請求 可能需要共享資訊怎麼辦?無疑不同的機房裡,訪問該Redis的速度會不一樣並且可能比較慢。
- 其二,keepalived + nginx。目前我們公司線上使用的是阿里雲的SLB,其實該方案根據雲棲社群的文章 是和keepalived + nginx的組合類似的,原理就在於做了一層TCP級別的負載均衡,使用VRRP協議,將一組機器(及其IP)組成一個虛擬 路由器,其中這個組的成員使用主從方式,主來承擔流量分發任務,當主掛了之後,從挺身而出,承擔主的任務,主恢復之後,便恢復 原來的主從模式。這需要路由器的配合,即支援VRRP。
那其實看起來還是有問題,路由器掛了怎麼辦?這也是單點故障,網線斷了怎麼辦?這也是單點故障,但是別忘了,網路是拓撲結構,只要 網路布的好,雖然請求會有點繞,但是最終是能到達目的地的。
參考資料: