1. 程式人生 > >我的微服務之路

我的微服務之路

還記得在14年的某一天,為生活所迫,走上了程式設計師這條路。到如今,已是第六個年頭了。所幸的是,寫程式碼是我人生所經歷的各種職業中最喜歡的職業。如無意外,我會一直做下去,直到生命終止。2019年即將過去,寫下這篇文字以作紀念,也希望給閱讀這篇文字的同學們一些啟發。特別是想要轉行程式設計師的,或者.NET、PHP想轉Java方向的程式設計師,希望能夠給你們一點鼓勵和幫助。

微服務是一個熱門的話題,作為一個在微服務上面實踐了4年多的老司機,說一下我的經歷。

15年我入職了一家新公司,負責一個商城系統的開發。鑑於以往的小小經驗,為了解決多業務系統共用一套使用者的需求。把使用者、使用者組、組織機構、角色許可權和Token從整個系統中獨立了出來。商城以及管理系統作為另外一個獨立的系統存在。後面又陸續開發了幾個系統,他們之間採用http協議進行介面的呼叫。無疑,這個僅僅是一個非常簡陋和原始的多服務架構。為什麼不算微服務架構呢?首先,單個服務仍然比較龐大。然後也沒有RPC框架,就是httpClient直接上。更沒有什麼服務註冊/發現、配置中心、閘道器、限流/熔斷、監控了,簡直要啥沒啥。不過這次把各個業務拆開來,為後面真正的微服務化奠定了基礎,同時也走出了重要的一步。由於採用的是.NET技術棧,所以後面在往真正的微服務系統轉化的路上踩了不少坑。真是說來話長,這裡暫且略過不表。

17年我從北京回到了杭州,進入了一家網際網路初創公司擔任架構師。初創公司嘛,前期都很簡陋,包括公司的業務系統也是。我的任務就是重新設計公司的業務系統,要滿足xxx和yyy,還有zzz。總之,要求相當地高大上。那個時候,微服務的概念已經蠻流行了,對於微服務,我也有了一些自己的理解和那麼一丟丟的實踐經驗。為了滿足老闆這個巨集大的遠景藍圖,沒說的,就是微服務,就是前後端分離。幾個架構圖一畫,果不其然,老闆非常滿意,轉頭就拿去忽悠投資人去了……

我們一個規劃了四個中心:
使用者中心,包含資源、使用者、使用者組、組織機構、角色許可權、租戶、驗證,共拆了7個服務。
訊息中心,負責訊息通知、簡訊、郵件、應用內訊息等,沒有進一步拆分服務。
支付中心,負責對接支付寶、微信、銀聯等支付通道,也沒有更多的拆分。
訂單中心,拆分成訂單領域服務和訂單管理服務兩個服務。

因為技術團隊是Java向,所以自然而然地採用了Spring全家桶,裡面什麼都有,真香。訊息中心和支付中心我負責了介面設計,訂單中心則只提出了領域服務和管理服務分離的原則,具體的設計是另一個架構師負責的。使用者中心對我而言輕車熟路,只是增加了租戶的概念,以支援多租戶平臺的需求。另外把資源服務搞起來,使得資源可配置。總體來說相當於用Java重新寫一遍程式碼。在重寫的過程中,由於Java語言的特性和C#還是有很多不同的地方,實現的思路也有所變化。用不同的語言來實現同一個需求,還是比較有趣的。感覺就像打開了一扇門,發現了一個新的世界。Spring boot也給了我很多的驚喜,經常會發現一些新的玩法,然後感嘆一聲:臥槽,居然還可以這樣搞!

這一次實踐,最大的問題是基礎強而業務弱。那時候阿里還沒有明確提出它的中臺戰略,而我們的系統 ,就已經有點中臺的意思了。從業務需求來看,其實根本不需要微服務,有點過度設計了。事實上僅僅1年之後,這家公司就嗚呼哀哉,煙消雲散了。當然這個結局的主要原因在於老闆而不在技術。而這些基礎服務的好處,則在我之後入職的新公司得到了體現。業務所依賴的基礎設施都已經建設好了,剩下的只需要關心業務的實現就夠了。就像國家已經給你通了高速公路網和高鐵、機場、港口什麼的都建好了,地方政府只需要一門心思搞經濟建設就好了。如果一個小國、窮國也這麼搞,估計會把自己搞死掉。基建真的燒錢啊,咱們國家也是攢了20多年的家當,抓住了國際形勢天時地利人和的機會才能這麼玩一次。

對於微服務系統來說,我們關注這三點就足夠了:一是微服務元件的選型,二是服務如何劃分,三是資料一致性問題如何解決。

微服務元件的選型問題,其實我也沒有太多的建議,因為我也僅僅接觸過Spring Cloud這一套。對我而言,Spring Cloud是比較成熟、易用的解決方案。支援的語言也很多,即使不支援,也很容易自己照著別的語言造個輪子來用。不過我到現在都沒有用過任何的配置中心,而是簡單搞了個配置資料庫,在jenkins裡面通過指令碼根據環境來替換配置。一直想自己搞個簡單的配置中心,但一直沒想好實現哪些功能,就一直擱置了。

第二個問題和第三個問題其實是存在相關性的。我的建議是,服務可以按邏輯是否完備(和其他服務不存在邏輯依賴)的標準進行最小粒度的劃分。特別是領域服務和領域上的業務管理服務,建議分拆成多個服務。因為領域資料相對穩定,而業務邏輯則很容易發生變化,分拆後既能有效提升領域服務的穩定性,同時也方便業務需求的隨時變更。資料分庫可以按領域來,譬如訂單資料 和訂單流程處理資料就沒必要分。也就是說,正常情況下,應該是多個服務共享一個數據庫。

對於資料一致性問題,我的經驗就是:
1、能夠使用資料庫事務保證的,就用資料庫事務。這也是為什麼資料庫按領域分的原因。
2、跨庫資料就是MQ一把梭,保證資料的最終一致性就可以了。如果是伺服器掉電之類的意外導致的丟資料引起的資料不一致,我的方案就是人工修復。只要資料可推導,就不存在不可修復的資料,人工跑個指令碼,分分鐘修好。

最後,我要和大家分享一下我的開源專案:xuanbg (Brian Xan) · GitHub。目前已經完成了上文提到的訊息中心的服務端和使用者中心的大部分服務端,後續還會增加一個財務中心以及它們的客戶端。我希望這個專案能夠為大家提供一些可組合的、開箱即用的微服務基礎設施,以降低轉換到微服務架構的開發成本。

已完成部分清單如下:
使用者服務:https://github.com/xuanbg/insight_user
租戶服務:GitHub - xuanbg/insight_tenant: 租戶服務
角色服務:https://github.com/xuanbg/insight_role
身份認證:GitHub - xuanbg/insight_auth: 身份驗證服務
閘道器:GitHub - xuanbg/gateway: 基於Spring Cloud Gateway的微服務閘道器
訊息中心:GitHub - xuanbg/insight_message: 訊息中心服務

未完成:
資源管理服務
組織機構服務
第三方支付統一接入
結算服務(收款、付款、退款)
資金賬戶服務
使用者賬戶服務
錢包管理服務

多租戶平臺管理客戶端
租戶系統管理客戶端
財務中心管理客戶