轉自:http://www.voidcn.com/article/p-dpwzjkho-bmt.htmlhtml
這是個系列故事,沒有讀過前兩回的不妨看看《持久化:Java帝國反擊戰》 和 《Java帝國之宮廷內鬥》數據庫
1 前情提要
上回說到IO大臣一直被JDBC大臣打壓, 爲了搞掉JDBC大臣, 他忍辱負重、歷經千辛萬苦終於搞出了分佈式事務的標準Java Transaction API, 滿心覺得此次一定翻身,可是沒想到國王爲了平衡朝中的權利, 竟然把JTA的管理權賜給了新任的JTA大臣。微信
更沒有想到的是,幸好本身沒有管理JTA,這個官方標準太強調強一致性,和民間的高併發系統要求的最終一致性不合拍,用不起來,變成了JTA大臣的燙手山芋。網絡
和民間表明深談了一次之後,原本已經心灰意冷的 IO大臣再次激起了雄心壯志: 必定要把JDBC大臣和JTA大臣搞掉。併發
2 基本可用
IO大臣立刻找了本身的心腹幕僚 InputReader , 交代了一項任務, 去民間考察這些高併發系統是怎麼折騰最終一致性的。分佈式
InputReader 連夜出發, 爲了避免引發JDBC大臣和JTA大臣的注意, 此次特地微服私訪。高併發
他任勞任怨, 跑遍了帝國大大小小几十個高併發系統, 與大量的民間領袖深刻地交換了意見。 他越談越驚心: 咱們老是高高在上地制定所謂官方標準,自我感受良好,實際上根本沒人用, 前有EJB, 今有JTA, 都是脫離了實際需求想出來的。性能
3個月後, InputReader 已經胸有成竹, 回到京城向大人彙報。spa
「大人, 據小人觀察, 咱們的JTA用的人確實不多,我如今是理解了他們民間所說的最終一致性了」設計
看着黑瘦的InputReader, IO大臣內心很是感動, 暗下決心: 等老夫控制了朝局, 必定給忠於本身的InputReader升兩級。
「仍是拿那個轉帳的例子來講吧」 InputReader 喝了口茶繼續說 「 假設兩個帳戶(呂秀才和郭芙蓉)在兩個獨立的數據庫中, 咱們原來設計的JTA是要求從呂秀才帳戶減去100兩銀子, 而後在郭芙蓉帳戶加上100兩銀子, 這兩個操做要麼所有作完,要麼所有不作, 可是在網絡的環境下, 這是不大容易作到的, 或者說在高併發的狀況下作到的代價過高。」
「這我理解,上次說了, 你說說民間究竟是怎麼實現的。」 IO大臣有點心急。
「其實特別簡單, 他們用了一個叫作消息隊列的東西來實現的, 大人請看 」 InputReader 展開了一張圖:
(碼農翻身注: 消息隊列的故事參見《Java 帝國之消息隊列》)
IO大臣看着圖: 「就這麼簡單?」
InputReader 說: 「小人舉的是個很是簡單的例子, 可是也能說明問題了, 你看咱們想從呂秀才帳戶轉100兩銀子給郭芙蓉, 須要在數據庫1發起一個事務, 從呂秀才帳戶扣除100兩, 而後還得向消息隊列插入一條給郭芙蓉帳號增長100兩的消息, 而後這個數據庫1的事務就結束了! 消息隊列中的消息會在某一刻被讀取出來,進行處理,給郭芙蓉的帳號增長100兩。」
「那給郭芙蓉添加100兩的消息何時會被處理呢? 」
「這個時間不肯定, 就看具體怎麼實現了, 好比有個後臺程序按期運行,讀取消息來處理 」
「那萬一消息隊列down機怎麼辦? 」
「不用怕, 消息隊列的數據都是持久化到硬盤上的, 不會丟失。」
「郭芙蓉這麼刁蠻, 這100兩銀子不能馬上到帳, 她還不把呂秀才給‘排山倒海’了?」
「大人,這就是關鍵了,你想啊, 假設數據庫2 down機了, 對郭芙蓉有兩種選擇: 一種是因爲系統緣由,轉帳操做徹底不能操做,另一種是能夠轉帳,可是錢稍後到帳,你說郭芙蓉會選哪種?」
IO大臣說: 「有道理,第一種狀況是徹底不可用, 第二種只是是部分可用, 郭芙蓉確定會先讓呂秀才轉帳, 反正100兩銀子是本身的, 早一點晚一點也不要緊。 」
「對的, 這就是最終一致性,數據雖然在某些時候看起來不一致,呂秀才的錢少了可是郭芙蓉的錢沒增長,這個時候錢在消息隊列中暫時存着呢。」
「這樣作有什麼好處?」
「好處很大,對於高併發的場景,轉帳的時候扣完錢, 向消息隊列插入消息,事務就結束了, 根本不用什麼兩階段提交, 性能很好。」
「嗯,不錯, 咱們再來看看一些細節吧。。。。。。」
3 走露風聲
天下沒有不透風的牆, JDBC大臣的密探早已潛伏在IO府中好多年了,雖然只是個端茶送水的下人, 可是不少消息都進入了他的耳朵, 而後又進入了JDBC大臣的耳朵。
JDBC大臣找來了JTA大臣前來商議, 爲了找一個同盟軍和強大的IO大臣對抗, JDBC大臣收買了不幹實事的JTA大臣。
「你知道嗎? IO老頭兒派人出去調查了, 我估計很快就會像上次那樣參我一本。」 JDBC大臣憂心忡忡。
「這IO老頭兒爲啥總是和大人過不去呢, 守好他那一畝三分地多好!」
「人的慾望都是無窮的,再說我這幾年確實打壓他比較厲害, 不說了,你先看看這張圖, 是咱們的臥底從IO府中偷出來的。」
JTA大臣抽了一口冷氣:「如今民間都這麼玩了? 不用JTA了? 」
「是啊, 你看他們的方法還不錯嘛, 基本可用,最終一致性。真是實踐中出真知啊」 JDBC大臣感嘆道,他在觀察JTA的反應。
「大人, 我建議我們搶先一步, 明天早朝就把這幅圖獻給陛下,陛下一高興,估計就會把這一起劃給我管了, 不不, 是給你管了。 」
「這合適嗎?」
「無毒不丈夫, 朝中爭鬥原本就是你死我活的, 大人不可太婦人之心了。」
「好,就這麼辦。」
4 宮廷激辯
國王已經厭倦了早朝, 厭倦了臣子們在朝中爭來爭去。
這天出奇的平靜, JDBC大臣和IO大臣沒有像以前那樣爭得不可開交, 國王正要宣佈 「有事啓奏,無事退朝」 , 一直以來戰戰兢兢的JTA大臣咳嗽了一聲, 發言了 :
「陛下,臣最近獲得一個民間上供的設計圖,說是民間用了一種新型辦法來處理高併發問題 」 JTA 一邊把偷來的圖紙呈上去,一邊用餘光迅速地掃了一眼IO大臣。
JDBC在一旁添油加火:「陛下,臣也看過這個設計, 以爲很是不錯, 建議帝國設立標準推廣。」
IO大臣一切都明白了,本身尚未出手,這倆老頭兒先下手爲強了。
國王天然是看不懂,聽到兩位大臣都這麼確定, 懶洋洋的說: 「愛卿此言不錯,這個既然屬於分佈式事務, JTA大臣,你來領銜把他設計出來。」
IO大臣看準時機,忽然出手:「陛下萬萬不可, 這個設計有重大缺陷啊!」
「什麼缺陷? 」 JDBC大臣和IO大臣齊聲問道。
IO大臣成竹在胸, 一切盡在計劃之中,那個圖紙只不過是個小誘餌而已,這兩個愚蠢的老頭兒果真上鉤。
「陛下,請看這個圖紙, 呂秀才給郭芙蓉轉帳的時候,圖紙中寫的是:」
「我想請問JDBC老頭兒, 不, 大臣, 這個事務同時操做了數據庫和一個消息隊列, 這兩個東西是徹底不一樣的, 請問你是怎麼實現的?不會仍是使用老掉牙的JTA吧」
(碼農翻身注: JTA不只僅能夠支持數據庫, 只要是支持XA協議的數據源均可以)
JDBC心中大叫很差,中計了! 唉,本身怎麼不仔細研究下圖紙呢, 這麼一個缺陷居然沒有發現, 冒冒失失地獻給陛下,真是不可饒恕啊!
但是他不甘心就此失敗, 稍必定神,馬上反擊: 「先不說缺陷問題, 我想問你這個圖紙剛纔只有陛下看了, 你怎麼知道其中內容?!」
IO大臣看到他反咬一口,豈能罷休 ,一不作二不休,乾脆撕破臉: 「陛下, 這張圖紙原本是我府中的InputReader 走遍帝國,遍訪民間疾苦畫出來的, 咱們知道有缺陷, 還沒來得及修改,就被他倆給偷了去 !」
「你血口噴人!」 JDBC和JTA有些心虛了。
「陛下,我已經抓住了偷竊圖紙的傭人, 隨時能夠傳喚。」
國王一切都明白了: 這些大臣之間的爭鬥真是無處不在啊, 天天如此,都不能讓我消停一天。
「愛卿,」 國王對IO大臣說, 「你先說說怎麼解決那個圖紙中的缺陷問題吧」
「陛下,其實有不少辦法, 好比這一種」 IO大臣從袖中掏出一個圖紙,舉了起來,讓你們都能看到:
「在這裏,咱們能夠添加一個‘事件表’, 轉帳開始的時候,把呂秀才的100兩銀子扣除, 同時還向事件表插入一行記錄: 須要向郭芙蓉轉100兩, 因爲這兩個表是在同一個數據庫中,因此直接使用本地事務就行。不用什麼分佈式事務。」
「你那個定時運行程序幹嗎?」 JTA大臣理解力有限
「就是定時運行, 從事件表中取出記錄, 向MQ寫入消息, 而後把記錄的狀態改爲‘DONE’, 這樣下次就不用再去取去處理了。 」
JDBC大臣很老練: 「那你這個定時運行程序也有問題啊, 好比說它讀了數據,向消息隊列寫入了消息, 還沒來得及把事件表的status 改成 ‘DONE’ 就崩潰了,等到定時運行程序重啓之後,豈再也不次讀取, 再次向MQ寫入消息,這樣郭芙蓉不就獲得了200兩銀子,整個系統就不一致了。」
IO大臣內心有點佩服, 這老頭兒仍是有兩把刷子的。 幸好我和InputReader討論過各類細節,要否則還真被他給問住, 那在陛下面前就悲催了。
5 冪等性
「其實這裏必須得引入一個概念: 冪等性」 IO大臣說
「迷瞪性? 這是什麼東西 」 JTA大臣大惑不解。
「是冪等性, mi ,四聲」 IO大臣對朝中有這樣不學無術佔據高位的傢伙感到很悲哀, 「這個冪等性說的是當你對一個事物操做的時候,能夠一直重複地操做,那個事物不受影響, 例如對郭芙蓉的帳號你查詢一千次,一萬次,帳戶餘額仍是那麼多,不會變化。 轉帳操做就不是一個冪等性操做。 每次操做都會致使帳號的變化。」
JDBC大臣也不禁地鄙視了下JTA老頭兒, 他說:「我明白了,你的意思是說那個定時運行的程序能夠出錯,能夠向消息隊列寫入屢次 ‘給郭芙蓉帳號增長100兩銀子’ 這樣的消息, 可是郭芙蓉那邊在執行的時候, 確定也要判斷以前是否執行過了, 若是沒有的話就增長, 若是執行過了就簡單的拋棄這個消息便可。 」
IO大臣向JDBC大臣投去了佩服的目光, 兩人目光相遇, 碰出來了惺惺相惜的火花。
「唉, 我要是早點和JDBC/IO大臣合做多好」 兩我的都在暗自吃後悔藥。
IO大臣說: 「是的, 郭芙蓉那邊在判斷是否已經執行過的時候,也須要查詢以前的執行記錄, 這就意味着以前執行過的也須要用一個表保存下來才行。」
「衆位愛卿, 看來已經討論得差很少了, 接下來怎麼辦啊?」
沒人出聲。
「那要不這樣, 既然是民間先作出來的東西, 咱們官方就不用去湊熱鬧了, 讓他們自生自滅吧」 國王祭出了「無爲而治」 的大法, 其實他實在不想再調停這幾個大臣之間的爭鬥了。
IO大臣想發言卻又忍住了,通過這一番較量, 他看清楚了各位大臣的實力, 也理解了國王的苦衷, 若是再這麼爭鬥下去陛下估計會龍顏大怒, 算了,不爭了。
傻傻的JTA大臣還不死心, 一直給JDBC大臣使眼色,只是JDBC大臣心中打定了和IO大臣同樣的主意,微閉雙眼開始養神了。
IO大臣心情平靜地回到家中, 幕僚們圍上來詢問結果, 他們還作着升官發財的好夢。
IO大臣看着這些急於知道結果而顯得特別飢渴的表情, 笑着擺了擺手, 一聲不響地離開了。
好久之後,朝中得知民間有個叫作Dan Pritchet的人, 把這種方法總結了一下,稱之爲BASE模型, 今後流行開來。
你看到的只是冰山一角, 更多精彩文章,請移步《碼農翻身2016文章精華》或者《碼農翻身2017上半年文章精華》
有心得想和你們分享? 歡迎投稿 ! 個人聯繫方式:微信:liuxinlehan QQ: 3340792577
碼農翻身
用故事講述技術