業務層,到底需不需要服務化?
很多公司,都實施了微服務架構,底層抽象出很多基礎數據服務。
基礎數據的訪問服務化之后,架構如上:
- 站點業務通過RPC接口,調用基礎數據服務;
- 基礎數據服務通過DAO,從db/cache獲取數據;
- db/cache存儲數據;
除了基礎數據的訪問需要服務化,業務層是否需要服務化?如果需要,什么時機進行服務化?這是本文要討論的兩個問題。
隨著時間的推移,系統架構并不會一成不變:
(1)隨著業務越來越復雜,業務會不斷進行垂直拆分;
畫外音:以58同城為例,有招聘、房產、二手、二手車、黃頁等多個業務。
(2)隨著數據越來越復雜,基礎數據服務也會越來越多;
畫外音,例如:用戶服務,訂單服務,搜索服務,推薦服務等。
于是系統架構變成了上圖這個樣子,業務垂直拆分,有若干個基礎數據服務:
- 垂直業務要通過多個RPC接口訪問不同的基礎數據服務,服務共享是服務化的特征;
- 每個基礎數據服務訪問自己的數據存儲,數據私有也是服務化的特征;
上面架構圖中的依賴關系是不是看上去很別扭?
- 基礎數據服務與存儲層之間連接關系很清晰;
- 業務站點層與基礎數據服務層之間的連接關系錯綜復雜,變成了蜘蛛網;
再舉一個更具體的例子,58同城列表頁站點如何獲取底層的數據?
- 首先調用商業基礎服務,獲取商業廣告帖子數據,用于頂部置頂/精準的廣告帖子展示;
- 再調用搜索基礎服務,獲取自然搜索帖子數據,用于中間自然搜索帖子展示;
- 再調用推薦基礎服務,獲取推薦帖子數據,用于底部推薦帖子展示;
- 再調用用戶基礎服務,獲取用戶數據,用于右側用戶信息展示;
- …
如果只有一個列表頁這么寫還行,但如果有招聘、房產、二手、二手車、黃頁等多個業務,都這么獲取共性數據,而只有少部分個性數據,每次都這么一個個調用基礎服務,有大量冗余、重復、每次必寫的代碼。
特別的,不同業務上游列表頁都依賴于底層若干相同服務:
- 一旦一個服務RPC接口有稍許變化,所有上游的系統都需要升級修改;
- 子系統之間很可能出現代碼拷貝;
- 一旦拷貝代碼,出現一個bug,多個子系統都需要升級修改;
如何讓數據的獲取更加高效快捷呢?
業務服務化,通用業務服務層的抽象勢在必行。
通過抽象通用業務服務層,例如58同城“通用列表服務”:
- 業務站點層,可以通過RPC接口,像調用本地函數一樣,調用通用業務服務,一次性獲取所有通用數據;
- 通用業務服務,也可以通過多次調用基礎數據服務提供的RPC接口,分別獲取數據,底層數據獲取的復雜性,全都屏蔽在了此處;
是不是連接關系也看起來更清晰?
這樣的好處是:
- 復雜的從基礎服務獲取數據代碼,只有在通用業務服務處寫了一次,沒有代碼拷貝;
- 底層基礎數據服務接口發生變化,只有通用業務服務一處需要升級修改;
- 如果有bug,不管是底層基礎數據服務的bug,還是通用業務服務的bug,都只有一處需要升級修改;
- 業務站點層獲取數據更便捷,獲取所有數據,只需一個RPC接口調用;
于是,當業務越來越復雜,垂直拆分的系統越來越多,基礎數據服務越來越多,底層數據獲取復雜性成為通用痛點的時候,就應該抽象出通用業務服務,簡化數據獲取過程,提高數據獲取效率,向上游屏蔽底層的復雜性。
最后再強調兩點:
(1)是否需要抽象通用業務服務,和業務復雜性,以及業務發展階段有關,不可一概而論;
畫外音:如果沒有多個業務線,大概率基礎服務就夠用。
(2)需要抽象什么通用業務服務,和具體業務相關;
畫外音:帖子列表業務服務,帖子詳情業務服務,是58同城特有的;而基礎服務,例如用戶,訂單,支付等基礎服務,基本上各個公司是類似的。
任何脫離業務的架構設計,都是耍流氓。
【本文為51CTO專欄作者“58沈劍”原創稿件,轉載請聯系原作者】