開發與維運

如何構建普適的企業級微服務架構(下)——阿里雲 MVP孫玄

快速成為頂級架構師的內功修煉

查看直播——如何構建普適的企業級微服務架構

查看上篇文章

(二)同步架構->異步架構

從上圖中我們可以看出圖中所示的架構是一種同步架構,而同步架構顯然是無法滿足所有的業務場景的,那麼我們怎麼將同步架構變成異步架構呢?

image.png

如上圖所示,在同步架構中,上游發送request給下游,下游再返回response給上游,而想將其變為異步架構也非常簡單,就是在上游和下游之間加入一個MQ(Message Queue,消息隊列)即可,這時雖然上游和MQ之間、下游和MQ之間仍然是同步架構,但是上游和下游已經變成了一個異步架構。

那麼利於MQ,我們如何將上述商品發佈服務的架構從同步架構轉為異步架構呢?我們一共可以在APP與網關層、網關層與業務邏輯層、業務邏輯層與數據請求層、數據請求層與數據層四個地方加上MQ,使得其成為異步架構,且MQ對整個系統生命週期來說,加的越靠前越好,但是APP與網關層之間加一個MQ的意義不是很大,因為網關層一般不會成為架構的瓶頸。因此,最好的做法就是我們在網關層和業務邏輯層之間加一個MQ,相當於以此MQ為界將業務的生命週期分為了上游和下游,由同步架構轉為了異步架構。

我們進一步思考,是不是所有的業務場景都可以用異步架構來做呢?當然不是。比如業務請求分為“讀”請求和“寫”請求,讀請求就很難用異步架構來做,而寫請求一般是可以的。但是,是否所有的寫請求都可以用異步架構來做呢?大家在工作中需要進一步的思考。

二、微服務架構下分佈式事務設計實踐

根據上文我們瞭解了微服務架構的拆分方式,那麼我們的DB該怎麼去做呢?假如用戶數據、商品數據、交易數據分佈在不同的DB中,而我們有些操作既涉及到用戶數據,又涉及到商品數據和交易數據,這種情況下顯然我們是無法去做一些本地事務的,那麼有什麼解決方法呢?這時我們要進行分佈式事務設計。

(一)分佈式事務破局

分佈式事務我們具體怎麼去做呢?首先要進行分佈式事務的破局,也就是實現長事務到短事務的轉變。假設我們現在有一個事務,涉及到下單、減庫存、支付三步,對應DB1、DB2、DB3三個數據庫,那麼我們想要設計一個分佈式事務的第一步就是將長事務變成一個短事務,也就將下單、減庫存、支付三步分開成三個事務,如果三個事務都成功了,那麼分佈式事務也就成功了,即便其中某一個事務N失敗了,那麼也只需要補償關聯的事務即可,也就是回滾N-1的事務。

(二)分佈式事務設計實例

image.png

這裡我們舉一個異步場景的例子,如上圖所示的商品交易場景,包括下單和支付兩個業務,在用戶下單之後,產生一個DB1,然後將消息傳輸給MQ,再由支付業務去消費MQ的消息,並操作自身的DB。

這種場景下,支付和下單是本地事務,但是MQ實際上不是一個本地事務,那麼這時候我們如何去進行分佈式事務設計呢?有人說可以將發送message和下單對DB1的操作放在一個本地事務裡面,也就上圖虛線框中部分。如果不細想,好像這樣的操作也沒有問題,但是在某些時候會出現問題,比如消費訂單消息超時了,前面取消了訂單,但是實際上後面的支付成功了,這樣就會造成數據庫的不一致,帶來嚴重的業務影響。

那麼這種情況下,我們怎麼去設計分佈式事務呢?一種比較好的方式是利用本地事務消息表來做。比如說剛才的下單業務,我們可以將下單和產生message都固化到本地數據中,下單對應一個表(本地事務操作表),產生message對應一個表(本地事務消息表),這樣就轉變成了一個本地事務,如果下單和產生message都成功,本地事務才成功,兩者有一個失敗,本地事務就失敗了。如下圖所示,本地操作和發送消息通過本地事務實現強一致性,再通過MQClient和MQ Server,就實現了分佈式事務的設計。

image.png

三、要點總結

本次直播中主要講解了:

(1)在構建普適的企業級微服務架構時如何進行架構的拆分,包括按照業務進行拆分的垂直拆分和按照功能(API)進行拆分的水平拆分兩種方式。在拆分完成之後,要根據業務場景來具體地考慮是使用同步架構還是異步架構。

(2)在進行分佈式事務設計的時候我們可以採取將長事務拆分成短事務的方式來完成架構設計,並列舉了一個異步場景下用本地事務消息表來完成分佈式事務設計的實例。

更多的詳細文檔大家可以掃描下面二維碼關注孫玄老師的公眾號《架構之美》和阿里雲MVP技術圈來查看。

image.png

四、QA

下面是直播中的一些問答整理:

問1:現在微服務有什麼難點沒有解決或者說解決方式不夠優雅呢?

答1:這個問題比較大,比如服務本身的設計和服務治理的分離就沒有被很好的解決,類似的還有其他很多都沒有被優雅的解決。

問2:使用MQ之後,訂單狀態更新不及時,怎麼處理?

答2:首先,你要找到訂單狀態更新不及時的原因是什麼,是因為消息量太大,還是因為下游消費的速度不夠,然後針對性的解決。

問3:微服務治理主要有哪些方案?

答3:治理這個話題比較大,通常說的治理除了功能之外,也包括一些其他的治理,比如監控、熔斷、限流等。最好的治理方式就是讓你的業務同學不需要關注服務治理,比如Istio方案。

問4:微服務一般按照領域來進行設計嗎?

答4:領域設計是一個比較好的思路,但是在實際中是比較複雜的,最好的方式還是剛才我們講的方式,便於更好地去落地。

問5:請問億級數據量用什麼數據庫?

答5:我個人認為億級數據量並不大,用什麼數據庫都能扛得住,比如MySQL等,問題在於這個億級的數據到底是怎麼樣的一個業務場景,需要提供什麼樣的特性,否則很難得到一個具體的回答。

問6:通常分庫和分表的方案是什麼呢?

答6:通常分庫是按照業務來進行垂直拆分,往往是按照領域來進行拆分的,比如拆分成用戶、商品、交易等;分表最好是按照查詢維度來進行拆分,比如按照用戶ID、商品ID等。另外,對於分庫和分表,阿里雲有比較好的解決方案,大家可以多多關注一下。

問7:gPRC多語言微服務需要部署在註冊中心嗎?可以直接使用K8s麼?

答7:在我看來,k8s等docker的東西解決的是運維部署的問題,如果你的公司原來已經有了註冊中心,那麼沒有必要為了使用k8s而把原來的註冊中心推翻重來;如果原來沒有的話,那就可以直接使用k8s service。

關鍵詞:微服務,分佈式事務,垂直拆分,水平拆分,MQ

快速成為頂級架構師的內功修煉

查看直播——如何構建普適的企業級微服務架構

查看上篇文章

Leave a Reply

Your email address will not be published. Required fields are marked *