知乎專欄 | 多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者” |
最近在群裡有人問關閉分散式事務的話題,詳細聽了他們需求後。我呵呵一笑,大約在15年前我就遇到過這種問題。
起因是這樣的,這是一個電商系統,架構師給出的架構是這樣的:
用戶中心:負責用戶註冊,登錄,用戶信息,錢包管理…… 商品中心:負責商品的管理,包括展示,價格和庫存管理…… 廣告中心:負責商品推廣,促銷…… 物流中心:負責訂單的物流…… 等等中心:負責等等……
每個中心都有一個獨立域名例如:
user.domain.com product.domain.com ad.domain.com search.domain.com m.domain.com ……
這種架構設計會存在一個問題,用戶每下一個訂單,都需要連接多個中心,做一連串調用,最終完成下訂單這個功能。因為用戶可能操作過程中終止購物流程,或者不可抗因素導致流程無法繼續。為此需要設計了一種分散式事務系統,用來解決事務回滾的問題。
所謂的分散式事務,是指跨伺服器實現資料庫生成與回滾操作,例如:用戶購物,瀏覽商品,添加購物車,選擇物流方式…… 這些數據產生在不同伺服器上,如果用戶取消訂單,數據將依次反向回滾。
無獨有偶,另一個跨境電商公司的同事也遇到了這種問題,苦苦找不到解決方案,想起了我,詢問我的意見。
有時候你會發現,人們會陷入思維邊界的陷阱,全力以赴在錯誤的方向上,無法自拔。
首先,劃分中心的架構思維,之所以會出現這種劃分方法,我認為跟我們的教育方式有關,導致了多數人都會沿用這種思維定式。
其次,分散式服務的確能解決他們遇到的問題,能想到分散式事務,證明他們智商沒有問題。但分散式事務不是最優解,是最差解決方案。
最後,出現了南轅北轍,在錯誤方向的道路上越走越遠。
大約在15年前我們也遇到了這個問題,幸好我及時出手糾正了架構設計的誤區,從而沒有走上分散式事務之路。
那時還沒有微服務的概念,也沒有容器技術,我們主要使用物理伺服器,在伺服器上運行多個實例。從BAT高薪挖來的架構師的思路跟上面一樣,將應用劃分成各種中心,並且要求每個中心都部署在獨立物理機上。劃分中心這種方式也與當時的開發模式有關,採用敏捷開發,分成多個小組,每個小組負責一個中心,小組間定義好信通介面,然後所有小組馬力全開,活就一起開幹了。現在想想簡單又粗暴,就如人體器官一樣,五臟六腑的聯繫不是通過一條神經實現的,他們的聯繫十分複雜。所以我們不能單獨思考每個中心,然後就認為把它們合起來就是一個整體。
如果再繼續下去,我們一定會去研發分散式事務。
此時有一個更好的機會等着我,於是我提出了離職申請,反正是準備離開了,也不怕得罪人,我想我應該在離職之前把這些問題跟公司說一下。
我向公司反映了目前面臨的所有問題,並且提出了兩個概念:
上面提出的兩點,直到今天也仍然適用,例如在微服務的拆分中。在我的職業生涯中,這兩個概念始終在指導我的團隊。下面我詳細說明兩個概念怎樣應用到實際的工作中。
我們還以電商系統舉例,用戶下單購物的工作流,如果是按照中心劃分,流程可能是這樣的:
用戶 —> 商品中心(瀏覽) —> 搜索中心(過濾)—> 用戶中心(添加購物車)—> 物流中心 (物流方式) —> 結算中心(支付結算/扣積分)—> 商品中心(扣庫存)—> 用戶中心 (完成)
數據流在,商品中心,搜索中心,用戶中心…… 伺服器中不斷傳遞,網絡延遲,網絡超時,網絡故障等等任何錯誤都可能影響用戶體驗。
如果是運行在一個實例中呢?確切的說,我們需要讓工作流運行在一個伺服器上,一個CPU、內存和硬碟上。這樣就沒有分散式事務的需求了,資料庫的事務處理解決了所有的問題,就這麼簡單!!!
基于這種法則,我們將幾套工作流歸類,放在一個實例中,放在今天就是微服務。同樣微服務的拆分也儘量滿足一套工作流在一個微服務客戶端上,避免請求過程出現,一個微服務調用另一個微服務的情況。