微服務架構通過將應用分解為一組小的、獨立的服務來實現,每個服務圍繞特定業務功能構建,并能獨立部署與擴展。這種架構增強了開發靈活性、提高了系統的可維護性和擴展性,使得團隊可以更快地響應變化和市場需求。
目錄
認識微服務
單體架構
微服務架構
微服務拆分
服務拆分原則
拆分時機
拆分細則
微服務工程結構
服務拆分實現
服務調用
認識微服務
單體架構
單體架構:顧名思義,整個項目中所有功能模塊都在一個工程中開發;項目部署時需要對所有模塊一起編譯、打包;項目的架構設計、開發模式都非常簡單。
適用場景;當項目規模較小時,這種模式上手快,部署、運維也都很方便,因此早期很多小型項目都采用這種模式。
項目的業務規模越來越大,團隊開發人員也不斷增加,單體架構就呈現出越來越多的問題:
-
團隊協作成本高:試想一下,你們團隊數十個人同時協作開發同一個項目,由于所有模塊都在一個項目中,不同模塊的代碼之間物理邊界越來越模糊。最終要把功能合并到一個分支,你絕對會陷入到解決沖突的泥潭之中。
-
系統發布效率低:任何模塊變更都需要發布整個系統,而系統發布過程中需要多個模塊之間制約較多,需要對比各種文件,任何一處出現問題都會導致發布失敗,發布耗時。
-
系統可用性差:單體架構各個功能模塊是作為一個服務部署,相互之間會互相影響,一些熱點功能會耗盡系統資源,導致其它服務低可用。
此時如果我們對系統做水平擴展,增加更多機器,資源還是會被這樣的熱點接口占用,從而影響到其它接口,并不能從根本上解決問題。這也就是單體架構的擴展性差的一個原因。
微服務架構
為了解決單體架構因為帶來的問題,于是微服務出現了。
微服務架構,首先是服務化,就是將單體架構中的功能模塊從單體應用中拆分出來,獨立部署為多個服務。同時要滿足下面的一些特點:
-
單一職責:一個微服務負責一部分業務功能,并且其核心數據不依賴于其它模塊。
-
團隊自治:每個微服務都有自己獨立的開發、測試、發布、運維人員,團隊人員規模不超過10人(2張披薩能喂飽)
-
服務自治:每個微服務都獨立打包部署,訪問自己獨立的數據庫。并且要做好服務隔離,避免對其它服務產生影響
問題解決:
問題一:由于服務拆分,每個服務代碼量大大減少,參與開發的后臺人員在1~3名,協作成本大大降低
問題二:每個服務都是獨立部署,當有某個服務有代碼變更時,只需要打包部署該服務即可
問題三:每個服務獨立部署,并且做好服務隔離,使用自己的服務器資源,不會影響到其它服務
當然,對于Java領域開發者來說,SpringCloud框架可以說是目前最全面的微服務組件的集合。
微服務拆分
服務拆分原則
拆分時機
在項目初期,尤其是初創項目,通常優先考慮敏捷開發以快速產出可投入市場的最小可行產品(MVP),以便盡早驗證項目的可行性。此時,采用簡單的單體架構較為常見,因其開發成本低、部署快速,即便項目最終不被市場接受,損失也相對較小。隨著用戶量增長和業務復雜度提升,再逐步向微服務架構遷移,盡管這可能會導致后期因代碼耦合面臨拆分難題。
相反,對于從立項就目標明確的大型項目,考慮到長期發展和擴展性,初期即選擇復雜的微服務架構進行設計。這種方式雖然前期需要更多的資源投入,但有利于后續的維護與擴展,避免了日后服務拆分的困擾。簡而言之:
初創小項目:先用單體架構快速上線測試市場反應,之后視情況轉向微服務(前易后難)。
大型明確項目:直接采用微服務架構規劃長遠發展,減少后期重構麻煩(前難后易)。
拆分細則
拆分目標角度:
高內聚:每個微服務的職責要盡量單一,包含的業務相互關聯度高、完整度高。
低耦合:每個微服務的功能要相對獨立,盡量減少對其它微服務的依賴,或者依賴接口的穩定性要強。
拆分方式角度:
縱向拆分:依據項目功能模塊進行拆分。例如,在一個電商應用中,可以將用戶管理、訂單管理、購物車、商品管理和支付等功能各自獨立為單獨的服務。這種方式提高了每個服務的內聚性,使得各服務專注于特定業務領域。
橫向拆分:識別并提取各個功能模塊中的共通業務邏輯作為通用服務。比如,無論是用戶登錄還是下單過程,都涉及到發送消息通知和記錄風控數據的操作。這些共用的功能可以被抽取出來,形成獨立的消息中心服務和風控管理服務。這樣做不僅提高了代碼復用性,減少了重復開發工作,而且由于接口相對穩定,不會造成服務間的過度耦合。
微服務工程結構
一般微服務項目有兩種不同的工程結構:
完全解耦
- 描述:每個微服務是一個獨立工程,可使用不同語言開發。
- 優點:服務間耦合度低。
- 缺點:各自獨立倉庫,管理復雜。
Maven聚合
- 描述:整個項目作為一個Project,各微服務為Module。
- 優點:代碼集中,便于管理和運維。
- 缺點:服務間存在耦合,編譯時間較長。
服務拆分實現
按照Maven聚合實現拆分對于小型項目更為合適。
針對于已經完成開發的項目,我們拆分一般按照以下步驟:
1.對于拆分服務的精確劃分,應盡量符合服務拆分原則
2.新建對于模塊,并且引入依賴,配置application.yaml等配置文件
3.正確引入實體類,controller,service,mapper等業務代碼
事實上,往往服務內都會需要進行,對于服務的調用,我們該如何跨服務調用?
服務調用
RestTemplate
Spring給我們提供了一個RestTemplate的API,可以方便的實現Http請求的發送。
先將RestTemplate注冊為一個Bean
@Configuration
public class RemoteCallConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
利用RestTemplate發送http請求
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://localhost:8081/items?ids={ids}",// 請求URL,包含占位符{ids}HttpMethod.GET,// 使用GET方法null,// 不使用請求體或請求頭new ParameterizedTypeReference<List<ItemDTO>>() {}, // 指定響應類型為List<ItemDTO>Map.of("ids", CollUtil.join(itemIds, ","))// 替換URL中的{ids}為逗號分隔的itemIds字符串);// 2.2.解析響應if(!response.getStatusCode().is2xxSuccessful()){// 查詢失敗,直接結束return;}List<ItemDTO> items = response.getBody();
測試完畢:實現服務之間進行遠程調用