Java 帝國之消息隊(duì)列
張家村的歷史
Java 帝國的張家村正在迎來一次重大的變革。
5年前網(wǎng)上購物興起的時(shí)候, 帝國非??春?, 決定向這個(gè)領(lǐng)域進(jìn)軍, 于是興建了張家村, 在這里安裝了Java 虛擬機(jī)和數(shù)據(jù)庫, 然后部署了一個(gè)基于Web的訂單系統(tǒng)和一個(gè)庫存系統(tǒng), 由張家村的人負(fù)責(zé)操作。
張家村的老村長很清楚, 說是兩個(gè)系統(tǒng), 其實(shí)是邏輯上的一種劃分方式, 在物理上兩個(gè)系統(tǒng)還是部署在一個(gè)虛擬機(jī)中。 那個(gè)時(shí)候用戶量少, 數(shù)據(jù)量也不大, 村民們只要使用這一個(gè)Java 虛擬機(jī)和數(shù)據(jù)庫就足夠了。
訂單和庫存系統(tǒng)運(yùn)轉(zhuǎn)一直很好, 用戶的訂單來了, 會(huì)在訂單系統(tǒng)中存下來, 然后通知庫存系統(tǒng)發(fā)貨。
你要問怎么通知? 老村長會(huì)告訴你說: 其實(shí)簡單的很, 就是普通Java 方法的直接調(diào)用, 調(diào)用庫存系統(tǒng)某個(gè)類的某個(gè)方法而已。 由于在同一個(gè)虛擬機(jī)之內(nèi), 效率極高 。
轉(zhuǎn)眼間5年過去了, 人類變得越來越懶, 越來越喜歡網(wǎng)上購物, 用戶量和數(shù)據(jù)量暴增, 再加上他們時(shí)不時(shí)搞個(gè)什么秒殺活動(dòng), 更是讓張家村變得不堪重負(fù)。 為了應(yīng)付洶涌而來的訂單, 張家村經(jīng)常徹夜燈火通明, 全村人三班倒才能勉強(qiáng)應(yīng)付。
老村長向鎮(zhèn)上報(bào)告了很多次都沒有回音, 要不是帝國的性能監(jiān)控部門發(fā)現(xiàn)了這個(gè)異常,還不知道要被瞞到什么時(shí)候。
還好,欽差王大人來了, 變革要開始了。
拆分
王大人經(jīng)驗(yàn)豐富, 目光如炬, 一眼就看出了問題, 立刻下達(dá)了***道命令: 拆分 ! 把訂單系統(tǒng)和庫存系統(tǒng)分開!
老村長說: “那拆開了以后,我們村還是放不下啊”
王大人道: “訂單系統(tǒng)還是留在張家村, 庫存系統(tǒng)挪到李家莊去”
老村長暗自思忖,訂單系統(tǒng)是直接面向用戶的,很重要, 張家村一定要保住, 至于庫存系統(tǒng),主要是后臺操作,挪走就挪走吧, 于是就答應(yīng)了。
拆分不是那么容易的, 訂單和庫存耦合的比較緊密, 現(xiàn)在要把庫存系統(tǒng)搬到李家莊的Java虛擬機(jī)和數(shù)據(jù)庫去,免不了一番劇烈的折騰。
在王大人的指導(dǎo)下, 原先那些直接的Java 方法調(diào)用,也被改成了Web 服務(wù) -- 張家村和李家莊雖然距離較遠(yuǎn) , 還是有網(wǎng)絡(luò)相通的。
現(xiàn)在用戶下了訂單以后, 先在張家村保存, 然后由張家村調(diào)用李家莊的Web服務(wù)來通知庫存系統(tǒng)。
數(shù)據(jù)庫自然也做了拆分, 老的庫存數(shù)據(jù)被導(dǎo)出來, 再導(dǎo)入到李家莊的新數(shù)據(jù)庫中 。
不管過程是多么艱難, 兩個(gè)系統(tǒng)還是分了家,李家莊喜氣洋洋、敲鑼打鼓的迎接了庫存系統(tǒng)的部署, 開始了試運(yùn)營。
新問題
由于只需要處理訂單, 張家村的負(fù)載一下子降了下來, 恢復(fù)了正常的作息。
可是好景不長,張家村很快發(fā)現(xiàn)李家莊對新系統(tǒng)根本不上心, 派了一個(gè)酒鬼小李去負(fù)責(zé)操作庫存Web服務(wù), 小李喝醉了啥都忘了, Web服務(wù)經(jīng)常用不了。
這還不算,李家莊是嚴(yán)格的日出而作, 日落而息, 張家村正在繁忙的處理訂單的時(shí)候, 李家莊已經(jīng)把系統(tǒng)關(guān)了,睡覺去了。
這可苦了張家村的小張,用戶提交了訂單, 去調(diào)用Web服務(wù)通知庫存發(fā)貨, 可是Web服務(wù)經(jīng)常不響應(yīng), 小張沒有辦法, 只好反復(fù)重試、等待一段時(shí)間后再試,導(dǎo)致一個(gè)訂單很長時(shí)間才能完成, 用戶體驗(yàn)極差, 大家怨聲載道。
小張向李家莊投訴了很多次都不管用,沒人搭理,跨村莊協(xié)作可真是難啊!
小張活干的不好,工分減少, 再這么下去,月底分糧的時(shí)候又要餓肚子了,小張想起來了自己經(jīng)歷過的《Java帝國之撥云見日識回調(diào) 》, 心里再次哀嘆: 為什么受傷的總是我?
晚上到家,小張苦思憫想: 原來訂單系統(tǒng)和庫存系統(tǒng)都在一個(gè)虛擬機(jī)中, 處理起來很方便, 但是現(xiàn)在是個(gè)遠(yuǎn)程的Web服務(wù), 酒鬼小李不給我返回結(jié)果, 我就沒法結(jié)束, 這是典型的同步操作, 能不能改成異步的呢?
我把一個(gè)訂單包裹發(fā)給小李, 他什么時(shí)候處理我就不用管了, 這樣我這邊的效率就會(huì)大大的提高! 可是現(xiàn)在的Web服務(wù)并不支持這種方式, 我怎么才能把包裹發(fā)過去呢?
消息隊(duì)列
小張徹夜未眠, 第二天一大早就去請教老村長。
村長說: “你能想到這一層,非常不錯(cuò)! 近來我也一直在考慮這個(gè)問題啊, 在大型的分布式系統(tǒng)中,怎么做異步通信是個(gè)大問題, 我想到了一個(gè)叫消息隊(duì)列的東西”
“消息隊(duì)列? 沒有聽說過”
“就拿你遇到的情況來說吧, 我們開發(fā)一個(gè)消息隊(duì)列,名稱我都想好了,就叫ZhangMQ(Zhang Message Queue), 把它部署在我們張家村和李家莊之間, 我們村產(chǎn)生的訂單, 你只要負(fù)責(zé)把訂單消息寫到這個(gè)隊(duì)列里就完事大吉了。 ”
“奧,李家莊的酒鬼小李醒了,就讓他從這個(gè)消息隊(duì)列中讀取消息,進(jìn)行處理,對吧”
“沒錯(cuò),這不就變成異步的了? 酒鬼小李不處理, 那就是他們的責(zé)任了”
"那訂單消息的格式需要和李家莊商量好, 另外次序也不能亂掉, 還有, 要是斷電了或者重啟了,消息隊(duì)列中的訂單消息也不能丟失 " 小張想的很深入
“沒錯(cuò),這些都是我們的ZhangMQ要考慮的,要實(shí)現(xiàn)持久化, 把訂單消息存到硬盤上”
“這真是不錯(cuò)“ 小張躍躍欲試 ”村長,我想去開發(fā)這個(gè)ZhangMQ, 一定要讓我參加啊“
”沒問題, 不過我當(dāng)前最重要的是說服李家莊, 讓他們來采用我們的消息隊(duì)列“
經(jīng)過據(jù)理力爭和艱難協(xié)商,李家莊終于同意了消息隊(duì)列的方案,畢竟對他們也沒啥損失, 也不用聽張家村沒完沒了的投訴了,只需要改一點(diǎn)點(diǎn)代碼,從消息隊(duì)列中讀取訂單即可。
小張和其他人在家里埋頭開發(fā)ZhangMQ, 半年后,ZhangMQ正式上線, 徹底解決了異步通信的問題。
前欽差王大人對張家村做了回訪,發(fā)現(xiàn)了消息隊(duì)列,贊不絕口,回去后就發(fā)來了褒獎(jiǎng)令,還下令在帝國推廣, ZhangMQ一下子出名了!
【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】