天天看點

傳統SSM項目改造SpringBoot微服務實踐

最近公司正準備從傳統SSM項目轉型微服務,筆者在其中負責了一部分改造計劃。是以,本文主要總結改造過程中的思路及實踐中遇到的問題。如表述不當,歡迎指正。

一.為什麼要改造單體應用

1.1.什麼是單體應用

傳統項目一般也是單體應用,而單體應用簡單來說就是一個war包中包含了該應用的所有業務功能,這樣的項目就是一個單體應用。

1.2.單體應用的利弊分析

絕大多數項目都是從單體應用開始的,在初期單體應用容易部署測試,且能很好的運作。然而随着需求的增加,項目不斷變得龐大,代碼庫也在急速膨脹,單體應用的缺點凸顯:

<1>複雜度高:整個項目包含的子產品非常多,子產品之間的邊界模糊,且互相依賴,項目十分複雜。

<2>可靠性低:一個子產品出了bug,或者OOM,可能導緻整個應用出現不可用,而導緻嚴重的生産事故。

<3>可維護性差:由于項目的高複雜度,修改代碼都需要經過深思熟慮,修複一個bug一個不小心就會觸發另一個功能的異常,可謂刀尖上跳舞。

<4>擴充性差:整個應用隻能作為一個整體去部署,而無法根據業務子產品的需要進行伸縮。比如A子產品通路的并發量高,需要多台機器來支撐,而B子產品通路的并發量低,隻需要一台機器。而由于這些子產品聚集在一個war包中,是以各個子產品隻能在機器的數量上互相妥協。

<5>單體應用的其他弊端:影響技術創新,引入更多技術債務等

1.3.小結

基于單體應用存在的問題,勢必需要對其進行改進,使其适應目前時代業務快速變化的需求,同時保證高可用性。目前,主流的思路有SOA架構和微服務體系兩種,而筆者公司采用後者,是以,下文以微服務體系為例進行展示。

二.改造前的準備

在改造單體應用前,需要做好準備工作。準備工作主要包括:指定改造所要達成的目标,明确改造的影響範圍,以及相應的知識儲備。

2.1.制定改造所要達成的目标

如下圖所示,改造後,動态密碼器服務将遷移到微服務體系中,而原有單體應用對動态密碼器的調用将會使用微服務體系所提供的服務。

傳統SSM項目改造SpringBoot微服務實踐

2.2.明确改造的影響範圍

2.2.1.改造對單體應用的影響範圍

本次改造僅涉及一個基礎服務:動态密碼器服務,影響範圍為調用到動态密碼器服務的業務功能。

2.2.2.資料庫的影響範圍

該服務對資料庫的影響範圍主要有動态密碼器存儲表,使用者表,第三方服務表共三張。其中使用動态密碼器存儲表存儲動态密碼器的資訊。另外,使用動态密碼器服務還需要查詢使用者表以及第三方服務表。

2.3.知識儲備

2.3.1.什麼是微服務

微服務就是将單一應用程式開發為一組小型服務的方法,每個服務運作在自己的程序中,服務間采用輕量級通信機制(通常為HTTP方式)。各個服務可以使用不同的語言開發,使用不同的資料存儲技術。

2.3.2.微服務體系需要用到的主要技術

<1>SpringBoot

Spring Boot是由Pivotal團隊提供的全新架構,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。它預設配置了很多架構的使用方式,就像maven整合了所有的jar包一樣。它具有少配置,開箱即用,輕量級等優點。是微服務體系建構中必不可少的技術之一。

<2>SpringCloud

作為現在微服務體系的主流技術,SpringCloud同樣具備開箱即用的特性。它無縫內建SpringBoot,且元件齊全,同時還擁有十分豐富的文檔和活躍的社群。另外,它也被喻為全家桶,擁有非常豐富的元件如Eureka,Ribbon,Feign,Hystrix,Zuul等。在這裡不詳細展開,有興趣的讀者可以閱讀我的Spring系列專欄,在那裡會有詳細的講解。

2.3.3.其他技術

除了上面所提到的Spring系列技術,讀者還需要掌握微服務體系的建構思路,隻有明确整個架構思路,才能更好的對單體應用進行改造。

傳統SSM項目改造SpringBoot微服務實踐

這裡簡單描述下,原有的單體應用中的子產品被拆分到基礎服務和使用者服務中,當單體應用需要請求使用者服務時,會通過Zuul網關,将請求發送給使用者服務;而在微服務之間,采用Feign來進行微服務的調用;各個微服務需要将自己注冊到Eureka注冊中心上,實作服務的暴露以供服務消費者調用。感興趣的讀者可以閱讀相關書籍。

三.開始改造

3.1.改造思路

下面開始做項目改造,在本次改造計劃中,主要目标是将動态密碼器服務遷移到微服務中,并在單體應用中的該服務調用轉移到對微服務的調用。具體思路如下:

3.1.1.改造微服務

<1>将動态密碼器服務的相關代碼遷移到微服務中,首先明确動态密碼器服務的主要功能是通過産生動态密碼來保證一些交易的安全操作,是以将其歸屬于基礎服務,是以将該服務遷移到基礎服務中,下文用base服務來指代基礎服務。

<2>在明确了服務所屬的具體位置後,還需要明确服務的依賴關系。動态密碼器服務在使用過程中,是一個使用者對應綁定一個動态密碼器,是以需要依賴使用者服務(下文用user服務來指代),同時,需要調用一些第三方服務,是以需要依賴第三方服務(下文用thirdparty服務來指代)。依賴後的微服務依賴關系如下:

傳統SSM項目改造SpringBoot微服務實踐

也就說,在改造動态密碼器服務的過程中,還需要将需要依賴的服務也一并遷移,将動态密碼器服務放入base服務中,依賴的使用者服務放到user服務中,而依賴的第三方服務則放到thirdparty服務中。

<3>資料源的改造

按照經典理論,不同的微服務應該擁有自己的資料源,但是在本次改造過程中,并沒有對資料源進行改造,而是直接連接配接之前的庫,原因主要有2個:第一是如果将對應服務的表也遷移出來,那麼之前單體應用所做的join等操作将會失效,需要考慮;第二是拆出後,資料庫數量會增多,增加運維成本,這個在前期需要盡量避免。

3.1.2.改造單體應用

改造完微服務後,就需要改造單體應用了,将之前單體應用中調用到動态密碼器服務的邏輯改成調用微服務的邏輯,采用HTTP+POST的方式進行調用,請求将通過Zuul網關發送到base服務中,而base服務将通過Feign調用user服務和thirdparty服務。

3.1.3.後續改進

<1>增加Hystrix熔斷器,做微服務的熔斷。

<2>增加日志配置,對關鍵位置進行日志輸出,以便後續排查問題。

3.1.4.廢棄舊邏輯

上述工作完成後,最後廢除原來的動态密碼器的舊邏輯,至此,傳統項目中的動态密碼器服務被徹底改造到微服務體系中。

3.2.改造過程中遇到的問題及解決

下面就改造過程中遇到的問題進行記錄并提出相應的解決方案:

<1>遷移過程中需要遷移較多的類,這些類的位置如何确定?

A:具體的邏輯類放在微服務包中,而需要被引入的類(vo類)放在API包中。

<2>引入的類如何使用?

A:引入的類需要被Spring容器管理,原有的單體應用通過xml的方式配置Bean,而在微服務中可以通過JavaConfig或者注解的方式來配置Bean。

<3>單體應用,微服務之間的調用手段?

A:單體應用調用微服務可以通過HTTP的方式進行遠端調用;而微服務調用微服務則通過Feign元件來調用。Feign元件可以做成API包的方式,需要調用時引入即可。

<4>某些微服務的Service層需要直接被調用如何處理?

A:對微服務的Service層單獨設定Controller層并且配置Feign Client即可。

<5>微服務都需要的公共配置(類)如何儲存?

A:主要有兩種方式。第一種方式是将公共配置類抽離,放到公共包中,需要時直接引入;第二種方式是在各個微服務之間做備援,不過這種方式管理上會有不便。是以,筆者采用第一種方式。

四.改造後

筆者在改造完成中,并沒有直接廢除舊邏輯,而是采用二者并存的方式。通過開關來控制動态密碼器服務的調用邏輯,如果打開開關,将會調用微服務的動态密碼器服務,如果關閉開關則會直接使用原有單體應用自身的動态密碼器功能,這主要是為了保證萬無一失。在出現問題時可以及時處理,減低微服務事故發生對項目的影響。後續上線後穩定一段時間,再移除開關,并廢除舊邏輯。

五.總結

單體應用向微服務的轉變是一項巨大的工程,裡面涉及很多理論基礎,需要深入學習才能較好的完成。同時,理論知識的學習,還需要深入的實踐才能熟練掌握。希望通過本文,讓讀者對整個改造過程有所了解,并能準确地運用在生産實踐中。

繼續閱讀