使用API​​閘道器幫助單體到微服務的平滑過渡

banq發表於2018-09-06
本文從閘道器角度討論了從單體遷移到微服務的三種方式,主要方向是確保新老系統平滑過渡,這些模式和最佳實踐值得一讀:

在我的諮詢工作中,我遇到了很多工程團隊,他們正在從單體應用遷移到基於微服務的應用程式,雖然我明白遷移模式幾乎成了陳詞濫調,但是遷移的細節方面往往都會被遺忘。我現在熱衷於討論其中一個主題 - 邊緣閘道器或API閘道器的角色。

遷移到微服務
一般情況下,在遷移開始時,下面這些明顯的主題會得到了很多關注:
1. 透過領域驅動設計進行領域域建模,引入“ 有界的上下文 ”;
2. 建立了持續交付管道;
3. 自動化基礎設施配置;
4. 增強的監控和記錄
5. 引入新技術Docker,Kubernetes,或服務網格或。

但是如何協調系統的演變和現有使用者流量的遷移?雖然你希望重構現有的應用程式架構並可能引入一些新技術,但你不希望破壞終端使用者的正常使用。

每個(使用者)旅程都從邊緣開始
在轉向基於微服務的應用程式時,我顯然不是第一個談論有效邊緣解決方案需求的人。事實上,Phil Calcado提出了擴充套件Martin Fowler最初的微服務先決條件,並發表文章:  "Calcado的微服務先決條件" , 他的第五個先決條件是“ 輕鬆進入邊緣 ”,Phil根據他的經驗談到,許多組織首次嘗試在他們的單體上部署新的微服務,只需將服務直接暴露給網際網路,這對於單個(簡單)服務會很奏效,但是該方法不能擴充套件,並且還強制呼叫客戶端在授權或資料聚合方面的特殊處理。

一個方案是可以將現有的單體應用用作閘道器,如果你有複雜且高度耦合的授權和身份驗證程式碼,那麼在將安全元件重構為新模組或服務之前,這可能是唯一可行的解​​決方案。

這種方法有明顯的缺點,就是要求必須使用任何新的路由資訊​​(可能涉及完全重新部署)來“更新”單體,以及所有流量必須透過單體。如果要將微服務部署到單獨的新結構或平臺(例如Kubernetes),後一個問題解決起來可能會特別昂貴,因為現在任何進入應用程式的請求必須在它接觸新平臺之前首先透過舊單體平臺進行路由。

可以使用邊緣閘道器或反向代理(例如,NGINX或HAProxy),因為他們可以提供許多優勢,提供的功能通常包括到多個後端元件的透明路由、標頭重寫、TLS終止等,以及橫切關注點。

無論最終如何提供請求。在這種情況下要問的問題是,是否要繼續使用此閘道器進行微服務實現?如果這樣做,是否應該以相同的方式使用它?

從VM到容器(透過編排)
正如我在本文的介紹中提到的,許多工程團隊也決定在更改應用程式架構同時遷移到新的基礎架構。這樣做的好處和挑戰在很大程度上依賴於上下文,但我看到許多團隊從虛擬機器(IaaS)直接遷移到容器和Kubernetes。

假設你決定將閃亮的新微服務打包到容器中並將其部署到Kubernetes中,那麼在處理邊緣流量方面面臨哪些挑戰?本質上有三種選擇,其中一種你已經讀過:

1. 使用現有的單體應用程式充當邊緣閘道器,將流量路由到單體服務或新的微服務。這裡可以實現任何型別的路由邏輯(因為所有請求都透過單體傳輸)並且可以在程式中呼叫驗證和授權。

2. 在現有基礎架構中部署和執行邊緣閘道器,基於URI和Http Header標頭將流量路由到單體服務或新服務。驗證和授權通常透過呼叫單體或重構的安全服務來完成。

3. 在新的Kubernetes基礎架構中部署和執行邊緣閘道器,基於URI和Http標頭將流量路由到單體服務或新服務。驗證和授權通常透過呼叫可在Kubernetes中執行的已經重構的安全服務來完成。

這三種情況比較如下:
1. 學習曲線是依次從低到高
2. 配置難度是依次從高到低
3. 自我服務能力是從低到高
4. 擴充套件性,前面兩種都很低,最後一種高擴充套件性。

一旦你選擇瞭如何實現邊緣閘道器,應該做出的下一個決定是如何改進系統,從廣義上講,你可以嘗試按原樣“strangle扼殺”單體,或者你把“單體”放在盒子,然後逐漸移開。

扼殺單體
Martin Fowler撰寫了一篇關於Strangler(扼殺)模式原理的精彩文章,儘管寫作已有十多年的歷史,但在嘗試將功能從一個單體遷移到更小的服務時,這個指導原則同樣也適用。

其核心模式描述了應該以服務的形式從單體中提取出功能,這些服務透過RPC或REST或透過訊息傳遞和事件與單體互動。隨著時間的推移,單體中的功能(和相關程式碼)將被淘汰,這導致新的微服務“扼殺了”現有的程式碼庫。這種模式的主要缺點是,只要單體仍處於服務狀態,你仍需要維護現有的基礎設施和正在部署微服務的新平臺,兩個平臺同時維護。

最早談論使用這種模式應用到微服務的公司是Groupon,早在2013年就有了“ I-Tier:拆除單體 ”。從他們的工作中可以學到許多教訓,但我們絕對不需要在2018年像他們那樣編寫自定義NGINX模組了,因為Groupon最初使用“Grout”,現在存在像Ambassador和Traefik這樣的現代開源API閘道器,它們使用簡單的宣告性配置來提供類似同樣功能。

Monolith-in-a-Box:簡化持續交付
我看到團隊遷移到微服務並部署到Kubernetes上的一種越來越常見的模式就是我所說的“monolith-in-a-box”。當我們 在2015年的ContainerSched會議上分享關於遷移notonthehighstreet.com的單體Ruby on Rails應用程式(親切地稱為MonoNOTH)到基於微服務架構的故事時,我與Nic Jackson一起討論了這個問題。

簡而言之,此遷移模式包括將現有的單體應用程式打包裝在容器中,並像執行任何其他新服務一樣執行它。如果你正在實施新的部署平臺,例如Kubernetes,那麼也可以在裡面執行單體。

這種模式的主要好處是持續交付管道的同質化 - 每個應用程式和服務可能需要自定義構建步驟(或構建容器)才能正確編譯和打包程式碼,但是在建立執行時容器之後,管道中的所有其他步驟都可以使用容器抽象作為部署工件。

這個模式最終目標是將您的單體元件部署到新基礎架構,並逐步將所有流量轉移到這個新平臺。這能在完成單體分解之前停用舊的基礎結構。如果遵循這種模式,那麼我認為在Kubernetes中執行邊緣閘道器更有意義,因為它最終將路由所有流量。


結論
從基於虛擬機器(VM)的基礎架構遷移到像Kubernetes這樣的雲本機平臺時,非常值得花時間實施有效的邊緣/入口解決方案來幫助遷移。

有多種選擇來實現這一點:使用現有的單體作為閘道器; 在現有基礎架構中部署或使用邊緣閘道器,在當前服務和新服務之間路由流量; 或在新的Kubernetes平臺中部署邊緣閘道器。

在Kubernetes中部署邊緣閘道器可以在實現諸如“Monolith-in-a-Box”之類的遷移模式時提供更大的靈活性,並且可以更快地向完全基於微服務的應用程式過渡。

Using API Gateways to Facilitate Your Transition f

相關文章