上個月(16/07)把一個大而全的應用拆分成一個個小的應用。
應用背景:
1.基於Spring Boot開發
2.依賴ActiveMQ,Kafka,Redis,Mongodb,MySQL等開源軟件
3.內部服務圖片服務器,分佈式計算平臺服務,檢索服務,消息推送服務等
拆分原因:
1.(原有的)應用模塊之間高度耦合,各個模塊都擔當了牽一髮而動全身的“角色”
2.應用的配置信息分佈到依賴個幾個服務的配置中,配置信息冗餘,對配置的修改改動地方過多
3.應用在依賴的基礎服務的時候,沒能遵循“依賴倒轉原則”,導致基礎服務升級,問題修復,功能增加時應用在面對變化,不夠靈活
4.應用定製化開發分支與主線決裂,無法滿足靈活定製化開發
拆分過程:
整個拆封過程中保持原有業務不變,逐步進行的。
1.先是把依賴基礎服務的部分抽取出來,應用對依賴服務的操作全部通過抽象出來的接口進行。然後通過具體實現來完成基礎服務的操作。比如:操作圖片服務器的操作通過ImageServerClient進行,操作分佈式計算平臺服務通過PccServerClient進行。
2.梳理應用的配置信息,比如圖片服務器配置,數據庫配置等,搭建Spring Cloud Config服務(支持git,svn,Local File 讀取配置文件)採用Local File的方式來管理配置文件;應用集成Spring Cloud Config Client ,配置信息統一才配置服務中讀取。
3.進行應用拆分,將提供Http請求接口的拆分爲WebApp,將提供RPC接口的拆分爲App。然後這兩類分別安裝實現的業務功能進行拆分。
拆分的WebApp,App仍然採用Spring Boot框架。
拆分結果:
1.WebApp通過Spring Session + Redis來實現Session共享
2.WebApp,App通過請求配置服務(Spring Cloud Config Server)完成配置文件的讀取,解決了拆封原因2的問題
3.拆分步驟1解決拆分原因3中的問題
4.各個獨立的應用之間除了webApp要session共享外,其它的通信,數據流向都是通過中間件來完成
5.解決拆分原因4的問題就更加容易了,定製化開發僅需要添加定製的應用即可
訪問應用:
1.應用是前後端分離,通過反向代理來完成Http請求到多個WebApp的轉發
2.外部系統可以通過Http請求,TCP/IP的方式分別訪問WebApp和App
拆分難點:
1.應用的模塊劃分,這個需要對應用業務流程,數據流向,依賴服務之間的調用關係以及通信協議清楚
2.避免爲拆分而拆分
3.團隊成員都能夠理解拆分的原因,清楚操作的過程,能夠想象到期望的結果
一個故事:
某一天女朋友包了兩種餃子:大肉蔥,韭菜雞蛋。
我:一起煮
女朋友:說分開煮
我:不嫌麻煩
女朋友:我不吃大肉
我:那煮好,不撈大肉給你就好了
女朋友:那大肉蔥煮爛了,咋辦!鍋裏全是肉味
大而全的應用就像是一個鍋煮各種餃子,小應用(微服務)就像是一鍋煮一類餃子。