在上一篇通知文章有說過,六月份會開始更新公衆號(固然一些好的文章我也會同步到博客中來,因此你們看到有些文章的內容和公衆號中的是同樣的),雖然如今已到月底了,但好歹也算沒有失言,遇上了末班車了。mysql
公衆號中有不少讀者留言,你們很期待能繼續更新《RF接口自動化系列》文章,放心,牛奶會有的,麪包也會有的,本身答應你們的,含淚也有完成的。nginx
不過本篇仍不會更新《RF接口自動化系列》的文章,放心,後續會更新,敬請期待~web
本篇會給你們介紹一下服務高可用的實現,大體也會分幾篇文章進行講解。redis
爲何忽然會講服務高可用,請看【背景】章節!算法
目前咱們組內的主服務器docker主機(ubuntu系統),承載運行了咱們組內(效率提高組)大部分對外提供的關鍵平臺服務sql
先來看一張圖吧docker
簡單粗暴地畫了一張精簡圖,從上圖中直觀地反映咱們docker主機的一個簡要架構圖(若是你以爲真實部署架構也是如此簡單, 那隻能說明你仍是太年輕了),用戶訪問咱們的應用服務,如訪問qa.xx.com應用服務(A),通過nginx代理,由nginx反向代理到實際應用服務A中。數據庫
這是常規應用部署最簡單的單點結構,但做爲這類關鍵服務節點,若是某天docker主機嗝屁了,那就意味着,全部運行在docker應用服務,就沒法對外提供服務,可能有的人會說,這種狀況,通常來講不會發生吧,好吧,前不久就發生的一宗由於機房中服務異常斷電,重啓後磁盤啓動異常的案例。apache
因此就引出了本文,經過高可用的方案來解決應用單點部署當發生異常長時間沒法對外提供服務的問題!ubuntu
高可用集羣中的節點通常是一主一備,或者一主多備,經過備份提升整個系統可用性。
而負載均衡集羣通常是多主,每一個節點都分擔請求流量
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拓撲圖中移除。)
高可用也就是你們常說的HA(High Availability),高可用的引入,是經過設計減小系統不能提供服務的時間,而不能保證系統可用性是能達到100%的!
高可用保證的原則是「集羣化」,或者叫「冗餘」:只有一個單點,掛了服務會受影響;若是有冗餘備份,掛了還有其餘backup可以頂上。
保證系統高可用,架構設計的核心準則是:集羣。
有了集羣以後,還不夠,每次出現故障須要人工介入恢復勢必會增長系統的不可服務實踐。因此,又每每是經過「自動故障轉移」來實現系統的高可用。
因此,實現高可用的兩個關鍵點:
集羣化
自動故障轉移
對於服務而言,一旦某個服務器宕機,就將服務切換到其餘可用的服務器上;
對於數據而言,若是某個磁盤損壞,就從備份的磁盤(事先就作好了數據的同步複製)讀取數據。
結合咱們上圖來看,要實現高可用的須要解決幾個問題:
一、服務集羣化,須要增長服務物理機 (利用現有的服務機或者新增購買一臺新的服務機,建議後者)
2、nginx請求代理集羣(請求入口需引入集羣,不然應用服務有集羣,nginx掛了,照樣game over,因此須要解決如何讓nginx能夠集羣,並能自動故障轉移)
三、應用服務集羣(服務不能單點部署,需集羣部署,一個服務提供者掛了,其它能夠頂上,因此須要解決如何讓應用服務能夠集羣,而且服務異常可自動故障轉移)
四、實現集羣后,需保證集羣間持久數據層是能保持同步一致的(mysql db、mongo db)
五、應用服務器集羣的Session管理。
整個系統的高可用,其實就是經過每一層的集羣(冗餘)+自動故障轉移來綜合實現的。
正如上述在須要解決的問題中,提到的:
一、要解決【客戶端層→反向代理層】的高可用:
【客戶端層】到【反向代理層】的高可用,是經過反向代理層的集羣(冗餘)來實現的。以nginx爲例:須要準備至少兩臺nginx,一臺對線上提供服務,另外一臺冗餘以保證高可用,常見的實踐是keepalived存活探測,相同virtual IP提供服務。
【正常圖】:
【其中一臺nginx嗝屁了】:
自動故障轉移:當nginx掛了的時候,keepalived可以探測到,會自動的進行故障轉移,將流量自動遷移到另一臺nginx,因爲使用的是相同的virtual IP,這個切換過程對調用方是透明的。
二、要解決【反向代理層→應用服務站點層】的高可用
【反向代理層】到【站點層】的高可用,是經過站點層的集羣(冗餘)來實現的。假設反向代理層是nginx,nginx.conf裏可以配置多個web後端,而且nginx可以探測到多個後端的存活性。
【正常圖】:
【其中一臺站點服務嗝屁了】:
自動故障轉移:當web-server服務站點掛了的時候,nginx可以探測到,會自動的進行故障轉移,將請求自動遷移到其餘的web-server,整個過程由nginx自動完成,對調用方是透明的。
三、雖然咱們的服務應用,沒有怎麼用到了緩存,但仍是想補充一個小章節說一下,【服務層】到【緩存層】的高可用
緩存層的數據集羣有幾種方式:第一種是利用客戶端的封裝,service對cache進行雙讀或者雙寫,也能夠經過主從同步的緩存來解決緩存層的高可用問題。
以redis爲例,redis自然支持主從同步,redis官方也有sentinel哨兵機制,來作redis的存活性檢測。
【正常圖】
【reids-Master嗝屁了】
自動故障轉移:當redis主掛了的時候,sentinel可以探測到,會通知調用方訪問新的redis,整個過程由sentinel和redis集羣配合完成,對調用方是透明的。
注:實際小型業務對緩存並不必定有「高可用」要求,更多的對緩存的使用場景,是用來「加速數據訪問」:把一部分數據放到緩存裏,若是緩存掛了或者緩存沒有命中,是能夠去後端的數據庫中再取數據的。(固然一些大型的流量平臺除外)
四、【服務層>數據庫層】的高可用
數據庫層通常集羣化都會採用了「主從同步,讀寫分離」架構,
以mysql爲例,能夠設置兩個mysql雙主同步,一臺對線上提供服務,另外一臺冗餘以保證高可用,常見的實踐是keepalived存活探測,相同virtual IP提供服務。
【正常圖】
【其中一臺數據庫嗝屁了】
自動故障轉移:當其中一個數據庫掛了的時候,keepalived可以探測到,會自動的進行故障轉移,將流量自動遷移到shadow-mysql,因爲使用的是相同的virtual IP,這個切換過程對調用方是透明的。
五、再來看看應用服務器集羣的Session管理,在集羣環境下,Session管理的幾種常見手段:
Session複製:集羣中的幾臺服務器之間同步Session對象,任何一臺服務器宕機都不會致使Session對象的丟失,服務器也只須要從本機獲取便可
Session綁定:利用負載均衡的源地址Hash算法,老是將源於同一IP地址的請求分發到同一臺服務器上。即Session綁定在某臺特定服務器上,保證Session總能在這臺服務器上獲取。(這種方案又叫作會話粘滯)
Cookie記錄Session:利用瀏覽器支持的Cookie記錄Session。(因此須要保證服務集羣間的域名一致來保證session id一致)
注:顯然session複製和綁定不符合高可用的需求。由於一旦某臺服務器宕機,那麼該機器上得Session也就不復存在了,用戶請求切換到其餘機器後由於沒有Session而沒法完成業務處理。
》》未完待續《《
另外,打一個小廣告,4月份與testerhome合做辦了一個測試開發線下培訓,我負責的課題持續集成建設與Docker容器化應用相關,目前課件對外特價優惠,感興趣的同窗能夠私聊找我哦~