在多個服務之間共享程式碼可能會成為專案團隊爭論的話題。服務涵括範圍越大,關於如何在不同服務之間共享功能的爭論就越激烈。
- 一方面,開發人員認為 DRY(不要重複自己)是正確的做法。
- 另一方則是 "無共享 "理念的支持者。
通常情況下,任何一方都無法提供明確的解決方案,因為在典型的企業應用程式中,可能存在許多不同型別的情況。很難提供一個能滿足所有可能需求的通用解決方案。
本文將介紹四種不同的程式碼共享方法,並探討每種方法的利弊得失。
1、程式碼複製
這是迄今為止在兩個獨立服務之間共享程式碼的最簡單方法。
在這種方法中,只需將共享程式碼複製到每個服務中即可。
- 雖然現在看來這可能是一種醜陋的駭客行為,但實際上這種技術在微服務架構的初期非常流行。
- 界限上下文 的概念推動了整個 "無共享架構 "的發展,從而使這種技術大行其道。
不過,經過多年的發展,這種方法在很大程度上已經失寵。
更新很困難
為什麼認為這種方法有問題?
試想一下,在共享或重複的程式碼中發現一個錯誤,或者需要對這部分程式碼進行重要修改。
- 您需要更新包含複製程式碼的所有服務。無論你如何努力,都可能會錯過某些服務的更新,從而導致問題。
- 此外,您還必須徹底測試所有這些服務。
對於大多數新專案,應避免使用這種技術。
但是,您有可能會發現這種方法被用於現有的應用程式中,您可能需要以適當的方式來處理它。
banq注:
更新困難本身是一個偽命題,不存在的問題,因為如果不同程式碼所在的上下文不同,所以才複製程式碼,更新這些複製程式碼時,需要仔細考慮,這個上下文中的程式碼更新是否適用於另外一種上下文,這種推理本身就避免了很多BUG。多次思考也許讓自己理解更深入。
2、共享庫
使用共享庫是跨多個服務重用程式碼的最常用技術。
共享庫是一種外部工件,如包含通用功能的 JAR 檔案、DLL 或 NPM 包。
我們的想法是,只需在任何需要它的服務中包含該共享庫,並使用它提供的功能即可。
優勢和問題
- 這種方法的主要優點是在編譯時將共享庫與服務繫結,從而更容易在開發和測試過程中發現問題。
- 這種方法的一個問題是共享庫的原始大小。不過,在測試和版本控制方面也有更大的問題,這就需要對共享庫的粒度進行權衡。
依賴性管理與變更控制
要決定採用哪種方法,您需要平衡依賴性管理和變更控制這兩股力量。
如果共享庫變得過大並被多個服務使用,那麼一旦對庫進行更改,即使更改與特定服務無關,每個服務也會受到影響。所謂影響,是指我們需要重建、重新測試和重新部署服務。此外,本地開發也變得更加困難,因為在同時修改共享庫和服務時,需要頻繁地進行構建和釋出步驟。
另一方面,如果共享庫的規模太小,就會使變更控制變得更容易。不過,最終可能會出現非常複雜的依賴關係矩陣。
一般來說,最好還是避免使用大型、粗粒度的共享庫。此外,良好的版本策略也有助於管理共享庫的變更範圍。
3、共享服務
共享庫包方法的主要替代方法是共享服務方法。
在這種策略中,使用者將所有常用功能提取到共享服務中,然後將其作為獨立流程部署。
獨立部署
使用這種技術,你可以將通用功能放到具有獨立部署路徑的單獨服務中,從而避免程式碼重用。
這種方法非常適合使用多種異質語言和平臺的環境。此外,與共享庫方法相比,對共享服務進行更改更加靈活。
潛在的權衡
這種方法有一些重要的權衡,例如:
- 更改風險--對共享服務的任何錯誤更改都有可能導致依賴於該服務的所有其他服務癱瘓。這是因為更改只能在執行時進行,而不能在編譯時進行。
- 效能 - 在共享服務方法中,每個服務都可能需要透過網路進行服務間呼叫。這意味著效能會受到整體網路延遲的影響。
- 可擴充套件性 - 共享服務還必須與依賴於共享服務的服務一起擴充套件。
- 本地開發 - 對於共享服務,如果很難在開發機器上覆制環境,本地開發就會相當困難。您必須與服務的不同消費者進行協調,還需要經歷多個構建和部署活動。
4、邊車Sidecars
應用程式通常由兩類功能組成:
- 領域
- 平臺
對於領域功能,我們通常會選擇松耦合和高內聚。
但是,日誌記錄、監控、身份驗證和斷路器等操作功能採用高耦合實現會更好。
你不希望每個服務團隊都重新發明操作功能。此外,整個組織或專案通常都需要標準化的解決方案。
要在多個服務中共享操作功能,Sidecar 模式是一個不錯的選擇。
實施 Sidecar
在此設定中,每個服務都包含 Sidecar 元件,負責操作功能。實現 Sidecar 有多種方法:
你可以使用 Kubernetes 等容器編排工具。在定義 Kubernetes Pod 時,規範包括兩個容器--主應用容器和 Sidecar 容器。它們共享同一個網路名稱空間,可以透過 localhost 進行通訊。
Istio 或 Linkerd 等服務網格框架也提供了一種實現 Sidecar 模式的方法,即在每個服務例項中注入一個代理。
使用六邊形架構
基本上,Sidecar 模式使用六邊形架構的概念,將領域邏輯與技術或基礎架構邏輯分離開來。
六邊形架構是一種軟體設計方法,它強調核心應用領域邏輯與外部元件(如日誌、身份驗證、監控等)之間的明確分離。
當然,重要的是要確保我們最終不會透過側車Sidecar 重複使用領域功能。
Sidecar 模式的潛在風險
西德卡圖案的主要風險在於,隨著時間的推移,它可能會變得過於龐大或複雜。
因此可能會出現以下幾個重要問題:
- 由於複雜性增加,維護變得耗時
- 大型Sidecar 可能會導致更多的資源消耗,並在容器化環境中產生資源爭用問題
總結
每種程式碼共享方法都有其利弊和需要考慮的利弊權衡。
程式碼複製是最簡單的程式碼共享方式,但在日後維護共享程式碼時會產生很多問題。
程式碼複製的一些大問題如下
- 測試變得非常麻煩,因為必須對每個受影響的服務進行徹底測試
- 找出影響足跡並不容易。很有可能遺漏關鍵服務,導致生產問題。
- 舊的服務可能仍在使用它,最好將其視為技術債務,並透過其他機制加以修復。
隨著服務足跡的成熟度提高,最好在共享庫或共享服務方法之間做出選擇。
隨著服務足跡的成熟度不斷提高,在共享庫或共享服務方法之間做出選擇始終是個好主意。
需要考慮以下幾點
- 共享庫在編譯時與服務繫結。這使得在開發過程中很容易發現潛在問題。
- 不過,對於共享庫,您需要在變更管理和依賴性管理之間做出權衡。
- 另一方面,共享服務非常適合異構環境,在這種環境下可能無法使用共享庫。
- 不過,共享服務在執行時與其他服務繫結。這使它們面臨變更風險、效能和可擴充套件性問題。
最後,還有一種使用 Sidecar 模式在服務間共享程式碼和功能的方法。
- Sidecar 模式是在多個服務之間共享交叉關注點的好方法。
- 您可以將其用於日誌記錄、監控和安全等各種功能。
- 這些關注點在不同服務間緊密耦合的情況下表現良好,因為您希望在整個服務範圍內提供一致性。