1. 前言
在上一篇通知文章有說過,六月份會開始更新公眾號(當然一些好的文章我也會同步到博客中來,所以大家看到有些文章的內容和公眾號中的是一樣的),雖然現在已到月底了,但好歹也算沒有失言,趕上了末班車了。
公眾號中有很多讀者留言,大家很期待能繼續更新《RF接口自動化系列》文章,放心,牛奶會有的,面包也會有的,自己答應大家的,含淚也有完成的。
不過本篇仍不會更新《RF接口自動化系列》的文章,放心,后續會更新,敬請期待~
本篇會給大家介紹一下服務高可用的實現,大致也會分幾篇文章進行講解。
為什么突然會講服務高可用,請看【背景】章節!
2. 背景
目前我們組內的主服務器docker主機(ubuntu系統),承載運行了我們組內(效率提升組)大部分對外提供的關鍵平台服務
先來看一張圖吧
簡單粗暴地畫了一張精簡圖,從上圖中直觀地反映我們docker主機的一個簡要架構圖(如果你覺得真實部署架構也是如此簡單, 那只能說明你還是太年輕了),用戶訪問我們的應用服務,如訪問qa.xx.com應用服務(A),經過nginx代理,由nginx反向代理到實際應用服務A中。
這是常規應用部署最簡單的單點結構,但作為這類關鍵服務節點,如果某天docker主機嗝屁了,那就意味着,所有運行在docker應用服務,就無法對外提供服務,可能有的人會說,這種情況,一般來說不會發生吧,好吧,前不久就發生的一宗因為機房中服務異常斷電,重啟后磁盤啟動異常的案例。
所以就引出了本文,通過高可用的方案來解決應用單點部署當發生異常長時間無法對外提供服務的問題!
3. 高可用與負載均衡的區別
-
高可用集群中的節點一般是一主一備,或者一主多備,通過備份提高整個系統可用性。
-
而負載均衡集群一般是多主,每個節點都分擔請求流量
4. 實現高可用的常用工具
-
ngnix
-
lvs (Linux虛擬服務器,是一個虛擬的服務器集群系統)
-
HAProxy(HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速並且可靠的一種解決方案。)
-
keepalived(這里說的keepalived不是apache或者tomcat等某個組件上的屬性字段,它也是一個組件,可以實現web服務器的高可用(HA high availably)。它可以檢測web服務器的工作狀態,如果該服務器出現故障被檢測到,將其剔除服務器群中,直至正常工作后,keepalive會自動檢測到並加入到服務器群里面。實現主備服務器發生故障時ip瞬時無縫交接。它是LVS集群節點健康檢測的一個用戶空間守護進程,也是LVS的引導故障轉移模塊(director failover)。Keepalived守護進程可以檢查LVS池的狀態。如果LVS服務器池當中的某一個服務器宕機了。keepalived會通過一 個setsockopt呼叫通知內核將這個節點從LVS拓撲圖中移除。)
5. 高可用不能解決什么
高可用也就是大家常說的HA(High Availability),高可用的引入,是通過設計減少系統不能提供服務的時間,而不能保證系統可用性是能達到100%的!
6. 高可用實施中有哪些問題需要解決
高可用保證的原則是“集群化”,或者叫“冗余”:只有一個單點,掛了服務會受影響;如果有冗余備份,掛了還有其他backup能夠頂上。
保證系統高可用,架構設計的核心准則是:集群。
有了集群之后,還不夠,每次出現故障需要人工介入恢復勢必會增加系統的不可服務實踐。所以,又往往是通過“自動故障轉移”來實現系統的高可用。
所以,實現高可用的兩個關鍵點:
-
集群化
-
自動故障轉移
對於服務而言,一旦某個服務器宕機,就將服務切換到其他可用的服務器上;
對於數據而言,如果某個磁盤損壞,就從備份的磁盤(事先就做好了數據的同步復制)讀取數據。
結合我們上圖來看,要實現高可用的需要解決幾個問題:
1、服務集群化,需要增加服務物理機 (利用現有的服務機或者新增購買一台新的服務機,建議后者)
2、nginx請求代理集群(請求入口需引入集群,否則應用服務有集群,nginx掛了,照樣game over,所以需要解決如何讓nginx可以集群,並能自動故障轉移)
3、應用服務集群(服務不能單點部署,需集群部署,一個服務提供者掛了,其它可以頂上,所以需要解決如何讓應用服務可以集群,並且服務異常可自動故障轉移)
4、實現集群后,需保證集群間持久數據層是能保持同步一致的(mysql db、mongo db)
5、應用服務器集群的Session管理。
7. 高可用架構實踐方案
整個系統的高可用,其實就是通過每一層的集群(冗余)+自動故障轉移來綜合實現的。
正如上述在需要解決的問題中,提到的:
1、要解決【客戶端層→反向代理層】的高可用:
【客戶端層】到【反向代理層】的高可用,是通過反向代理層的集群(冗余)來實現的。以nginx為例:需要准備至少兩台nginx,一台對線上提供服務,另一台冗余以保證高可用,常見的實踐是keepalived存活探測,相同virtual IP提供服務。
【正常圖】:
【其中一台nginx嗝屁了】:
自動故障轉移:當nginx掛了的時候,keepalived能夠探測到,會自動的進行故障轉移,將流量自動遷移到另外一台nginx,由於使用的是相同的virtual IP,這個切換過程對調用方是透明的。
2、要解決【反向代理層→應用服務站點層】的高可用
【反向代理層】到【站點層】的高可用,是通過站點層的集群(冗余)來實現的。假設反向代理層是nginx,nginx.conf里能夠配置多個web后端,並且nginx能夠探測到多個后端的存活性。
【正常圖】:
【其中一台站點服務嗝屁了】:
自動故障轉移:當web-server服務站點掛了的時候,nginx能夠探測到,會自動的進行故障轉移,將請求自動遷移到其他的web-server,整個過程由nginx自動完成,對調用方是透明的。
3、雖然我們的服務應用,沒有怎么用到了緩存,但還是想補充一個小章節說一下,【服務層】到【緩存層】的高可用
緩存層的數據集群有幾種方式:第一種是利用客戶端的封裝,service對cache進行雙讀或者雙寫,也可以通過主從同步的緩存來解決緩存層的高可用問題。
以redis為例,redis天然支持主從同步,redis官方也有sentinel哨兵機制,來做redis的存活性檢測。
【正常圖】
【reids-Master嗝屁了】
自動故障轉移:當redis主掛了的時候,sentinel能夠探測到,會通知調用方訪問新的redis,整個過程由sentinel和redis集群配合完成,對調用方是透明的。
注:實際小型業務對緩存並不一定有“高可用”要求,更多的對緩存的使用場景,是用來“加速數據訪問”:把一部分數據放到緩存里,如果緩存掛了或者緩存沒有命中,是可以去后端的數據庫中再取數據的。(當然一些大型的流量平台除外)
4、【服務層>數據庫層】的高可用
數據庫層一般集群化都會采用了“主從同步,讀寫分離”架構,
以mysql為例,可以設置兩個mysql雙主同步,一台對線上提供服務,另一台冗余以保證高可用,常見的實踐是keepalived存活探測,相同virtual IP提供服務。
【正常圖】
【其中一台數據庫嗝屁了】
自動故障轉移:當其中一個數據庫掛了的時候,keepalived能夠探測到,會自動的進行故障轉移,將流量自動遷移到shadow-mysql,由於使用的是相同的virtual IP,這個切換過程對調用方是透明的。
5、再來看看應用服務器集群的Session管理,在集群環境下,Session管理的幾種常見手段:
-
Session復制:集群中的幾台服務器之間同步Session對象,任何一台服務器宕機都不會導致Session對象的丟失,服務器也只需要從本機獲取即可
-
Session綁定:利用負載均衡的源地址Hash算法,總是將源於同一IP地址的請求分發到同一台服務器上。即Session綁定在某台特定服務器上,保證Session總能在這台服務器上獲取。(這種方案又叫做會話粘滯)
-
Cookie記錄Session:利用瀏覽器支持的Cookie記錄Session。(所以需要保證服務集群間的域名一致來保證session id一致)
注:顯然session復制和綁定不符合高可用的需求。因為一旦某台服務器宕機,那么該機器上得Session也就不復存在了,用戶請求切換到其他機器后因為沒有Session而無法完成業務處理。
》》未完待續《《
另外,打一個小廣告,4月份與testerhome合作辦了一個測試開發線下培訓,我負責的課題持續集成建設與Docker容器化應用相關,目前課件對外特價優惠,感興趣的同學可以私聊找我哦~