Java程式設計師面試必備的知識點
策略 1——停止挖掘
Law of Holes 是說當自己進洞就應該停止挖掘。對於單體式應用不可管理時這是最佳建議。換句話說,應該停止讓單體式應用繼續變大,也就是說當開發新功能時不應該為舊單體應用新增新程式碼,最佳方法應該是將新功能開發成獨立微服務。如下圖所示:
除了新服務和傳統應用,還有兩個模組,其一是請求路由器,負責處理入口(http)請求,有點像之前提到的 API 閘道器。路由器將新功能請求傳送給新開發的服務,而將傳統請求還發給單體式應用。
另外一個是膠水程式碼(glue code),將微服務和單體應用整合起來,微服務很少能獨立存在,經常會訪問單體應用的資料。膠水程式碼,可能在單體應用或者為服務或者二者兼而有之,負責資料整合。微服務通過膠水程式碼從單體應用中讀寫資料。
微服務有三種方式訪問單體應用資料:
- 換氣單體應用提供的遠端 API
- 直接訪問單體應用資料庫
- 自己維護一份從單體應用中同步的資料
膠水程式碼也被稱為容災層(anti-corruption layer),這是因為膠水程式碼保護微服務全新域模型免受傳統單體應用域模型汙染。膠水程式碼在這兩種模型間提供翻譯功能。術語 anti-corruption layer 第一次出現在 Eric Evans 撰寫的必讀書 Domain Driven Design,隨後就被提煉為一篇白皮書。開發容災層可能有點不是很重要,但卻是避免單體式泥潭的必要部分。
將新功能以輕量級微服務方式實現由很多優點,例如可以阻止單體應用變的更加無法管理。微服務本身可以開發、部署和獨立擴充套件。採用微服務架構會給開發者帶來不同的切身感受。
然而,這方法並不解決任何單體式本身問題,為了解決單體式本身問題必須深入單體應用做出改變。我們來看看這麼做的策略。
策略 2——將前端和後端分離
減小單體式應用複雜度的策略是講表現層和業務邏輯、資料訪問層分開。典型的企業應用至少有三個不同元素構成:
-
表現層——處理 HTTP 請求,要麼響應一個 RESTAPI 請求,要麼是提供一個基於 HTML 的圖形介面。對於一個複雜使用者介面應用,表現層經常是程式碼重要的部分。
-
業務邏輯層——完成業務邏輯的應用核心。
-
資料訪問層——訪問基礎元素,例如資料庫和訊息代理。
在表現層與業務資料訪問層之間有清晰的隔離。業務層有由若干方面組成的粗粒度(coarse-grained)的 API,內部包含了業務邏輯元素。API 是可以將單體業務分割成兩個更小應用的天然邊界,其中一個應用是表現層,另外一個是業務和資料訪問邏輯。分割後,表現邏輯應用遠端呼叫業務邏輯應用,下圖表示遷移前後架構不同:
單體應用這麼分割有兩個好處,其一使得應用兩部分開發、部署和擴充套件各自獨立,特別地,允許表現層開發者在使用者介面上快速選擇,進行 A/B 測試;其二,使得一些遠端 API 可以被微服務呼叫。
然而,這種策略只是部分的解決方案。很可能應用的兩部分之一或者全部都是不可管理的,因此需要使用第三種策略來消除剩餘的單體架構。
策略 3——抽出服務
第三種遷移策略就是從單體應用中抽取出某些模組成為獨立微服務。每當抽取一個模組變成微服務,單體應用就變簡單一些;一旦轉換足夠多的模組,單體應用本身已經不成為問題了,要麼消失了,要麼簡單到成為一個服務。
排序那個模組應該被轉成微服務
一個巨大的複雜單體應用由成十上百個模組構成,每個都是被抽取物件。決定第一個被抽取模組一般都是挑戰,一般最好是從最容易抽取的模組開始,這會讓開發者積累足夠經驗,這些經驗可以為後續模組化工作帶來巨大好處。
轉換模組成為微服務一般很耗費時間,一般可以根據獲益程度來排序,一般從經常變化模組開始會獲益最大。一旦轉換一個模組為微服務,就可以將其開發部署成獨立模組,從而加速開發程序。
將資源消耗大戶先抽取出來也是排序標準之一。例如,將記憶體資料庫抽取出來成為一個微服務會非常有用,可以將其部署在大記憶體主機上。同樣的,將對計算資源很敏感的演算法應用抽取出來也是非常有益的,這種服務可以被部署在有很多 CPU 的主機上。通過將資源消耗模組轉換成微服務,可以使得應用易於擴充套件。
查詢現有粗粒度邊界來決定哪個模組應該被抽取,也是很有益的,這使得移植工作更容易和簡單。例如,只與其他應用非同步同步訊息的模組就是一個明顯邊界,可以很簡單容易地將其轉換為微服務。
如何抽取模組
抽取模組第一步就是定義好模組和單體應用之間粗粒度介面,由於單體應用需要微服務的資料,反之亦然,因此更像是一個雙向 API。因為必須在負責依賴關係和細粒度介面模式之間做好平衡,因此開發這種 API 很有挑戰性,尤其對使用域模型模式的業務邏輯層來說更具有挑戰,因此經常需要改變程式碼來解決依賴性問題,如圖所示:
一旦完成粗粒度介面,也就將此模組轉換成獨立微服務。為了實現,必須寫程式碼使得單體應用和微服務之間通過使用程序間通訊(IPC)機制的 API 來交換資訊。如圖所示遷移前後對比:
此例中,正在使用 Y 模組的 Z 模組是備選抽取模組,其元素正在被 X 模組使用,遷移第一步就是定義一套粗粒度 APIs,第一個介面應該是被 X 模組使用的內部介面,用於啟用 Z 模組;第二個介面是被 Z 模組使用的外部介面,用於啟用 Y 模組。
遷移第二步就是將模組轉換成獨立服務。內部和外部介面都使用基於 IPC 機制的程式碼,一般都會將 Z 模組整合成一個微服務基礎框架,來出來割接過程中的問題,例如服務發現。
抽取完模組,也就可以開發、部署和擴充套件另外一個服務,此服務獨立於單體應用和其它服務。可以從頭寫程式碼實現服務;這種情況下,將服務和單體應用整合的 API 程式碼成為容災層,在兩種域模型之間進行翻譯工作。每抽取一個服務,就朝著微服務方向前進一步。隨著時間推移,單體應用將會越來越簡單,使用者就可以增加更多獨立的微服務。 將現有應用遷移成微服務架構的現代化應用,不應該通過從頭重寫程式碼方式實現,相反,應該通過逐步遷移的方式。有三種策略可以考慮:將新功能以微服務方式實現;將表現層與業務資料訪問層分離;將現存模組抽取變成微服務。隨著時間推移,微服務數量會增加,開發團隊的彈性和效率將會大大增加。
最後
俗話說,好學者臨池學書,不過網路時代,對於大多數的我們來說,我倒是覺得學習意識的覺醒很重要,這是開始學習的轉折點,比如看到對自己方向發展有用的資訊,先收藏一波是一波,比如如果你覺得我這篇文章ok,先點贊收藏一波。這樣,等真的沉下心來學習,不至於被找資料分散了心神。慢慢來,先從點贊收藏做起,加油吧!
好啦,由於文章篇幅限制,面試題答案詳解我就不在這裡展示出來了,如果你需要這份完整版的面試題答案詳解資料點選這裡免費領取
另外,給大家安排了一波學習面試資料:
以上就是本文的全部內容,希望對大家的面試有所幫助,祝大家早日升職加薪迎娶白富美走上人生巔峰!