網(wǎng)站建設(shè)可擴(kuò)展的重要性(下篇):分布式消息隊(duì)列的處理
一、可擴(kuò)展性架構(gòu)利用分布式消息隊(duì)列降低系統(tǒng)耦合性:
如果模塊之間不存在直接調(diào)用那么新增模塊或者修改模塊就對(duì)其他模塊影響最小,這樣系統(tǒng)的可擴(kuò)展性無疑更好一些。
1.事件驅(qū)動(dòng)架構(gòu)
事件驅(qū)動(dòng)架構(gòu)(Event Driven Architecture):通過在低耦合的模塊之間傳輸事件消息,以保持模塊的松散耦合,并借助事件消息的通信完成模塊間合作,典型的EDA架構(gòu)就是操作系統(tǒng)中常見的生產(chǎn)者消費(fèi)者模式。在大型網(wǎng)站架構(gòu)中,具體實(shí)現(xiàn)手段有很多,最常用的是分布式消息隊(duì)列,如圖7-1所示。
網(wǎng)站建設(shè)可擴(kuò)展性架構(gòu)經(jīng)驗(yàn)分享示意圖7-1利用消息隊(duì)列實(shí)現(xiàn)的事件驅(qū)動(dòng)架構(gòu)
消息隊(duì)列利用發(fā)布訂閱模式工作,消息發(fā)送者發(fā)布消息,一個(gè)或者多個(gè)消息接收者訂閱消息。消息發(fā)送者是消息源,在對(duì)消息進(jìn)行處理后將消息發(fā)送至分布式消息隊(duì)列,消息接受者從分布式消息隊(duì)列獲取該消息后繼續(xù)進(jìn)行處理??梢钥吹剑l(fā)送者和消息接受者之間沒有直接耦合,消息發(fā)送者將消息發(fā)送至分布式消息隊(duì)列即結(jié)束對(duì)消息的處理,而消息接受者只需要從分布式消息隊(duì)列獲取消息后進(jìn)行處理,不需要知道該消息從何而來。對(duì)新增業(yè)務(wù),只要對(duì)該類消息感興趣,即可訂閱該消息,對(duì)原有系統(tǒng)和業(yè)務(wù)沒有任何影響,從而實(shí)現(xiàn)網(wǎng)站業(yè)務(wù)的可擴(kuò)展設(shè)計(jì)。
消息接受者在對(duì)消息進(jìn)行過濾、處理、包裝后,構(gòu)造成個(gè)新的消息類型,將消息繼續(xù)發(fā)送出去,等待其他消息接受者訂閱處理該消息因此基于事件(消息對(duì)象)驅(qū)動(dòng)的業(yè)務(wù)架構(gòu)可以是系列的流程。
由于消息發(fā)送者不需要等待消息接受者處理數(shù)據(jù)就可以返回,系統(tǒng)具有更好的響應(yīng)延遲;同時(shí),在網(wǎng)站訪問高峰,消息可以暫時(shí)存儲(chǔ)在消息隊(duì)列中等待消息接受者根據(jù)自身負(fù)載處理能力控制消息處理速度,減輕數(shù)據(jù)庫(kù)等后端存儲(chǔ)的負(fù)載壓力。
2.分布式消息隊(duì)列
隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),分布式消息隊(duì)列可以看作將這種數(shù)據(jù)結(jié)構(gòu)部署到獨(dú)立的服務(wù)器上,應(yīng)用程序可以通過遠(yuǎn)程訪問接口使用分布式消息隊(duì)列,進(jìn)行消息存取操作.進(jìn)而實(shí)現(xiàn)分布式的異步調(diào)用,基本原理如圖7-2所示。
網(wǎng)站建設(shè)可擴(kuò)展性架構(gòu)設(shè)計(jì)流程示意圖7-22分布式消息隊(duì)列架構(gòu)原理
消息生產(chǎn)者應(yīng)用程序通過遠(yuǎn)程訪問接口將消息推送給消息隊(duì)列服務(wù)器,消息隊(duì)列服務(wù)器將消息寫入本地內(nèi)存隊(duì)列后立即返回成功響應(yīng)給消息生產(chǎn)者。消息隊(duì)列服務(wù)器根據(jù)消息訂司列表查找訂閱該消息的消息消費(fèi)者應(yīng)用程序,將消息隊(duì)列中的消息按照先進(jìn)先出(FIFO)的原則將消息通過遠(yuǎn)程通信接口發(fā)送給消息消費(fèi)者程序。
目前開源的和商業(yè)的分布式消息隊(duì)列產(chǎn)品有很多,比較著名的如Apache ActiveMQ等,這些產(chǎn)品除了實(shí)現(xiàn)分布式消息隊(duì)列的般功能在可用性、伸縮性、數(shù)據(jù)一致性、性能和可管理性方面也做了很多改善。
在伸縮性方面,由于消息隊(duì)列服務(wù)器上的數(shù)據(jù)可以看作是被即時(shí)處理的,因此類似于無狀態(tài)的服務(wù)器,伸縮性設(shè)計(jì)比較簡(jiǎn)單。將新服務(wù)器加入分布式消息隊(duì)列集群中,通知生產(chǎn)者服務(wù)器更改消息隊(duì)列服務(wù)器列表即可。
在可用性方面,為了避免消費(fèi)者進(jìn)程處理緩慢,分布式消息隊(duì)列服務(wù)器內(nèi)存空間不足造成的問題,如果內(nèi)存隊(duì)列已滿,會(huì)將消息寫入磁盤,消息推送模塊在將內(nèi)存隊(duì)列消息處理完以后,將磁盤內(nèi)容加載到內(nèi)存隊(duì)列繼續(xù)處理。
為了避免消息隊(duì)列服務(wù)器宕機(jī)造成消息丟失,會(huì)將消息成功發(fā)送到消息隊(duì)列的消息存儲(chǔ)在消息生產(chǎn)者服務(wù)器,等消息真正被消息消費(fèi)者服務(wù)器處理后才刪除消息。在消息隊(duì)列服務(wù)器宕機(jī)后,生產(chǎn)者服務(wù)器會(huì)選擇分布式消息隊(duì)列服務(wù)器集群中其他的服務(wù)器發(fā)布消息。
分布式消息隊(duì)列可以很復(fù)雜,比如可以支持ESB(企業(yè)服務(wù)總線)、支持SOA(面向服務(wù)的架構(gòu))等;也可以很簡(jiǎn)單,比如用MySQL也可以當(dāng)作分布式消息隊(duì)列:消息生產(chǎn)者程序?qū)⑾?dāng)作數(shù)據(jù)記錄寫入數(shù)據(jù)庫(kù),消息消費(fèi)者程序查詢數(shù)據(jù)庫(kù)并按記錄寫入時(shí)間戳排序,就實(shí)現(xiàn)了個(gè)事實(shí)上的分布式消息隊(duì)列,而且這個(gè)消息隊(duì)列使用成熟的MySQL運(yùn)維手段,也可以達(dá)到較高的可用性和性能指標(biāo)。
二、網(wǎng)站建設(shè)可擴(kuò)展性架構(gòu)利用分布式服務(wù)打造可復(fù)用的業(yè)務(wù)平臺(tái)
使用分布式服務(wù)是降低系統(tǒng)耦合性的另一個(gè)重要手段。如果說分布式消息隊(duì)列通過消息對(duì)象分解系統(tǒng)耦合性,不同子系統(tǒng)處理同個(gè)消息;那么分布式服務(wù)則通過接口分解系統(tǒng)耦合性,不同子系統(tǒng)通過相同的接口描述進(jìn)行服務(wù)調(diào)用。
回顧網(wǎng)站架構(gòu)發(fā)展歷程,網(wǎng)站在由小到大的演化過程中,表現(xiàn)為整個(gè)網(wǎng)站是由單應(yīng)用系統(tǒng)逐步膨脹發(fā)展變化而來,隨著網(wǎng)站功能的日益復(fù)雜,網(wǎng)站應(yīng)用系統(tǒng)會(huì)逐漸成為個(gè)巨無霸,如圖7-3所示。
一個(gè)應(yīng)用中聚合了大量的應(yīng)用和服務(wù)組件,這個(gè)巨無霸給整個(gè)網(wǎng)站的開發(fā)、維護(hù)、部署都帶來了巨大的麻煩。巨無霸應(yīng)用系統(tǒng)帶來如下幾點(diǎn)問題:
1.編譯、部署困難:對(duì)于網(wǎng)站開發(fā)工程師而言,打包構(gòu)建一個(gè)巨型應(yīng)用是件痛苦的事情,也許只是修改了行代碼,輸入build命令后,抽完支煙,回來看,還在building;又去喝了杯水,回來看,還在building;又去了次廁所,回來看,還在building;好不容易build結(jié)束, 看編譯失敗,還得重來……
2.代碼分支管理困難:復(fù)用的代碼模塊由多個(gè)團(tuán)隊(duì)共同維護(hù)修改,代碼merge的時(shí)候總會(huì)發(fā)生沖突。代碼merge一般發(fā)生在網(wǎng)站發(fā)布的時(shí)候,經(jīng)常和發(fā)布過程中出現(xiàn)的其他問題互相糾結(jié)在起,顧此失彼,導(dǎo)致每次發(fā)布都要拖到半夜三更。
3.數(shù)據(jù)庫(kù)連接耗盡:巨型的應(yīng)用、大量的訪問,必然需要將這個(gè)應(yīng)用部署在個(gè)大規(guī)模的服務(wù)器集群上.應(yīng)用與數(shù)據(jù)庫(kù)的連接通常使用數(shù)據(jù)庫(kù)連接池,以每個(gè)應(yīng)用10個(gè)連接計(jì),一個(gè)數(shù)百臺(tái)服務(wù)器集群的應(yīng)用將需要在數(shù)據(jù)庫(kù)上創(chuàng)建數(shù)干個(gè)連接。數(shù)據(jù)庫(kù)服務(wù)器上,每個(gè)連接都會(huì)占用一些昂貴的系統(tǒng)資源,以至于數(shù)據(jù)庫(kù)缺乏足夠的系統(tǒng)資源進(jìn)行般的數(shù)據(jù)操作。
4.新增業(yè)務(wù)困難:想要在一個(gè)已經(jīng)如亂麻般的系統(tǒng)中增加新業(yè)務(wù),維護(hù)舊功能,難度可想而知:一腳踩進(jìn)去,發(fā)現(xiàn)全都是雷,什么都不敢碰。許多新工程師來公司半年了,還是不能接手業(yè)務(wù),因?yàn)椴恢浪卸嗌?。于是就出現(xiàn)這種怪現(xiàn)象:熟悉網(wǎng)站產(chǎn)品的“老人”忙得要死,加班加點(diǎn)干活;不熟悉網(wǎng)站產(chǎn)品的新人幫忙就出亂,跟著加班加點(diǎn);整個(gè)公司熱火朝天,加班加點(diǎn),卻還是經(jīng)常出故障,新產(chǎn)品遲遲不能上線。
深圳網(wǎng)站建設(shè)公司認(rèn)為解決方案就是拆分,將模塊獨(dú)立部署,降低系統(tǒng)耦臺(tái)性。拆分可以分為縱向拆分和橫向拆分兩種縱同拆分:將個(gè)大應(yīng)用拆分為爹個(gè)小應(yīng)用,如果新增業(yè)務(wù)較為獨(dú)立,那么就直接將其設(shè)計(jì)部署為個(gè)獨(dú)立的Web應(yīng)用系統(tǒng)。
橫向拆分:將復(fù)用的業(yè)務(wù)拆分出來.獨(dú)立部署為分布式服務(wù),新增業(yè)務(wù)只需要闊用這些分布式服務(wù).不需要依賴具體的模塊代碼,即可快速搭建個(gè)應(yīng)用系統(tǒng),而模塊內(nèi)業(yè)務(wù)邏輯變化的時(shí)候,只要接口保持致就不會(huì)影響業(yè)務(wù)程序和其他模塊。如圖7-4所示。
網(wǎng)站建設(shè)可擴(kuò)展性架構(gòu)流程示意圖7-4業(yè)務(wù)及模塊拆分獨(dú)立部署的分布式服務(wù)架構(gòu)
縱向拆分相對(duì)較為簡(jiǎn)單,通過梳理業(yè)務(wù),將較少相關(guān)的業(yè)務(wù)剝離,使其成為獨(dú)立的Web應(yīng)用。而對(duì)于橫向拆分,不但需要識(shí)別可復(fù)用的業(yè)務(wù),設(shè)計(jì)服務(wù)接口,規(guī)范服務(wù)依賴關(guān)系,還需要一個(gè)完善的分布式服務(wù)管理框架。好了,其他具體應(yīng)用我們也許需要在現(xiàn)實(shí)中見招拆招。網(wǎng)站建設(shè)公司旨在通過本文對(duì)我們客戶在規(guī)劃大型網(wǎng)絡(luò)應(yīng)用平臺(tái)的時(shí)候有一定的前瞻性,并不是需要我們的客戶自己動(dòng)手來搭建平臺(tái),搭建這些事情您有需要可以聯(lián)系我們的在線客戶,為您提供更為詳細(xì)的建站方案策略。謝謝關(guān)注,博納網(wǎng)絡(luò)編輯整理。