最迷人的微服務 開發、理解、維護

微服務是個迷人的東西,易於開發、理解、維護,能夠挑選適合技術、獨立部署、易於擴充等,若曾被單體(Monolithic)架構應用程序「蠱毒」過,面對各類對微服務優勢的歌頌,應該會心癢難耐。只是,咱們須要哪些微服務呢?開展一個全新架構?這本質上就違反微服務的精神!數據庫

大爆炸或重構服務器

單個微服務也許是簡單的,然而爲了串起多個微服務,微服務架構充滿許多名詞,組態伺服、服務註冊與發現、負載平衡、斷路器、路由網關等,單個微服務宣稱的易於開發、理解、維護等優勢,依賴在高門坎的基礎設施與架構策略之上,光是要理解就不容易,進一步地,還需考慮如何適當安插在應用程序的哪一個環節,並且,真的須要用上所有的東西嗎?若是打算採納微服務的動機,是來自於對單體應用程序的想法,而且想要從無到有創建各個服務,將之組合起來,由於沒有歷史包袱,這應該比較簡單吧?網絡

 

然而,事先規畫的服務真的有用嗎?值得獨立出來?會不會實際上只有單個服務與之溝通,也從沒有過彈性擴充的需求呢?大爆炸式的(Big Bang)重寫成微服務架構,就像Martin Fowler說的:能保證的就是「大爆炸」!從另外一個角度來看,若是真能作出個全新架構來取代單體應用程序,單體應用程序自己在架構上,應該是沒有什麼大問題,微服務架構中確實充滿着許多基礎設施及策略考慮,不過服務之間的關係在規畫上,與開發上耳熟能詳的Program to interface、模塊化等概念,實質上是相似的,既然單體應用程序自己在架構上沒有太大問題,從中抽取服務的成本,應該會低於重寫應用程序的成本,那又何須重寫呢?想要大爆炸式地以微服務架構重寫應用程序,以擺脫單體架構應用程序中組件、模塊間的耦合等歷史包袱,只會令開發者更疲於奔命而不切實際,以重構方式逐步清理,逐步抽取服務,讓應用程序隨着時間推移,逐漸瓦解爲多個微服務,或許是更爲務實的作法!架構

 

重構的策略模塊化

重構的策略之一是重構單體應用程序,使之更遵循MVC架構的分層概念,讓呈現層、商務層與儲存層,彼此之間都有更清晰的界線,更具體地說,就是運用接口(對象之間的協議,而不是Java中的interface)溝通、隔離變化,若架構中各層之間有着清晰界線,就會出現可抽換的模塊,一塊一塊的模塊可能就暗示着,它們是可抽取的服務,在進一步抽取時,遇到的阻力會少一點。讓商務層與儲存層間有着清楚的界線,有助於看清有這些商業規則,以及各自須要的儲存邏輯,也就有助於數據庫上的分離,讓個別模塊可以擁有個別的數據儲存,由於在抽取成服務以後,個別服務會擁有本身的數據庫,也由於如此,個別服務能夠選擇更適合的資料儲存方案。單體架構應用程序中,在數據儲存上,每每錯綜複雜,例如,在應用關係數據庫時,若表格之間有緊密相關的操做,那麼,這些表格可能屬於同一個模塊;若表格數量衆多,並且有着複雜的操做關係,那麼,數據庫表格之間也需重構,不然的話,表示單一模塊過於巨大,承載了過多的職責,將來,就算抽取成服務,可能也是個「巨」服務,而不是「微」服務。微服務

在單體應用程序重構、抽取服務期間,應用程序可能會須要知足新的需求,這時,不該該直接在單體應用程序中繼續加入程序代碼,以免單體應用程序繼續肥大下去。在〈Refactoring a Monolith into Microservices〉(https://goo.gl/u1Et1m)中,也談到了重構單體應用程序的幾個策略,其中之一就,是中止挖掘(Stop Digging),試着將新需求實做爲服務,透過路由,將新需求的請求轉發給新的服務,舊的需求轉發給單體應用程序,而單體應用程序與新服務之間透過膠合程序代碼來溝通。版本控制

逐步抽取服務對象

單體應用程序中可能有許多的模塊,然而沒必要在一開始就所有都抽取成爲服務,若是單體應用程序中的模塊有着清晰的界線,並且多個應用程序存在着重用該模塊的需求,纔來考慮將該模塊抽取爲服務,這能夠做爲微服務粒度考慮的依據之一,避免服務過大或太小,若是將來其餘服務對於該服務中某模塊有着重用的需求,該服務能夠進一步將該模塊抽取成爲服務。在抽取出多個服務以後,不一樣的服務之間,也許會共享某些組態信息。例如,多個服務都須要郵件服務,而郵件服務的組態信息相同,在多個服務間直接複製組態是很簡單的一件事,然而,這就跟複製程序代碼同樣,將來若組態變動,就須要記得逐一更新應用程序的組態設定。像是《Spring Microservices in Action》第三章就談到,組態管理的重要性常常被忽略,做者甚至面對過12,000個組態檔案的遷移難題。blog

 

在抽取服務以後,就要開始重視組態管理問題,跟程序代碼管理相似,組態須要視需求而重構,決定採用哪一種組態方式。更進一步地,也會有版本控制之類的需求,衍生出專用的組態供應者,以及對應的組態消費者。而當組態的供應與消費,須要透過網絡來供給與消費時,組態供應者就會以服務器的形式實現,也就須要決定組態交換時的協議、格式等,以便組態消費者進行組態的取得、更新等。在抽取服務的過程當中,單體應用程序與服務,服務與服務之間,透過API接口溝通,不見得要立刻採用任何微服務基礎設施方案,在既有技術方案下逐步進行服務抽取,令單體應用程序本來的客戶端不察覺功能上的變化(符合重構基本精神)。而這些步驟的進行,可能至關緩慢而踏實,在〈StranglerApplication〉(https://goo.gl/cCuxwL),Martin Fowler用絞殺藤蔓逐步剝奪被寄生樹生存空間,來比喻大規模重構應用程序的這個過程。接口

 

逐步套用基礎設施

是否套用微服務基礎設施,也是依需求而定,也許既有的技術在抽取出服務以後,就足以應付需求,那麼,就不見得要用上任何基礎設施方案,畢竟,每增長一個方案,就是增長一層技術上的難度,維護的門坎也會隨之上升,更況且,問題並不僅有在採用哪一個技術方案,更可能是在於採用哪一個架構策略。若是須要彈性地擴充,試着採用服務註冊與發現;在須要考慮服務狀態不佳、避免服務連鎖性癱瘓下,再加上斷路器的方案;在客戶端多樣化,想要避免曝露個別服務細節、以橫切關切點方式,對某些客戶端加以控管、限制API開放與否等時,再來設置網關路由等策略。值得一提的是,〈Netflix成爲第一間徹底上雲的大型企業〉(https://goo.gl/yywVFV)的經驗值得借鏡,其中,對於速度、規模,以及策略三個階段,也有着分層式架構等相似考慮。總而言之,對於微服務的架構,不要一開始就想要用上所有的基礎設施或策略,重構會是更務實的作法!

相關文章
相關標籤/搜索