從微服務開始(一):優勢和注意事項
簡介
目前,在沒有提出術語“微服務”的情況下,是無法對原生雲架構進行單獨的討論的。隨著越來越多的開發人員和架構師考慮利用這種架構風格,出現了很多優秀的文章,但是有一些新的文章完全忽略了微服務的要點。一個典型的例子是,有的文件建議,將應用程式包構建的更小(“微”),就是微服務。
本篇部落格是四部系列文章中的開始,幫助大家更好的理解什麼是微服務,並且如何高效的使用它們。在這篇介紹性文章中,我們將介紹微服務的優勢,討論一些在建立基於微服務的應用時會遇到的挑戰。第二部分當中,我們將介紹如何將微服務和容器進行結合使用,如果利用編排和容器管理工具,比如Kubernetes。第三部分討論微服務的設計原則和微服務
微服務的優勢
在瞭解微服務為什麼具有如此的吸引力之前,我們應該先看看微服務是什麼。儘管對於微服務架構還沒有標準,業內所公認的微服務架構需要遵循如下的所提的幾個設計要點和特點:
通常,你會考慮使用微服務架構來設計由小型的自主服務組成的應用。這些服務是鬆耦合的,只通過API進行通訊,複雜性也更低,它們通常只專注於應用中某個業務功能(有邊界上下文)的單個功能。基本上,由服務組成的應用將會取代基於大型單一程式碼庫的單體應用程式,每一個服務具有它自己的程式碼庫和狀態,能夠由更小規模的敏捷開發團隊進行獨立的管理。這能夠使企業對他們的應用的一部分使用更快、更敏捷的方式進行開發、部署和更新工作,因此能夠對新的市場需求和競爭狀況進行更及時更靈活的響應。
下圖展示了一個使用微服務架構建立的簡單應用。
圖1:一個基於微服務的應用,有三個微服務
隨著快速的市場響應和敏捷性成為使用微服務架構的主要動力,最大的問題就是,為什麼會有這樣的敏捷性和速度?答案就是微服務的最主要的優勢。
獨立部署
對於大型的單體應用,快速可靠地部署會成問題。考慮這樣的場景,你需要引入一個新的特性,比如為使用者配置增加一個新的欄位,或者簡單的修復一個bug。單體應用通常都作為一個單一的整體應用進行建立和部署,在對整個應用的建立和測試時,要確保小的變化不會影響到應用的其他元件。整個應用必須也要被重新部署,包括所有其他沒有變化的元件。不算應用的大小、技術和流程所需的事件,單單進行建立、部署和更新就要花費很多時間。
基於微服務的架構中,就像圖1中所展示的,如果你遵循了鬆耦合的最佳實踐,你只需要對需要進行特性變化或者關鍵bug修復的那個服務進行更新和部署。如果你對一個服務的修改需要進行回滾,它能夠在不影響生產環境中其他服務的情況下完成。這使得讓大型應用保持敏捷,並且能夠更快和更頻繁的進行部署更新成為可能。
獨立擴充套件
在雲端,應用通常是靠增加主機數量來實現擴充套件的,稱之為例項。基本上,每一個應用會建立多個主機例項,每一個主機例項都帶有一個應用例項,並且為這些例項提供負載均衡。在單體應用中,如果僅僅有一個應用特性需要進行額外的擴充套件,整個應用都需要被擴充套件,因此有更多的主機例項需要被新增,相比微服務模式,需要更高的成本。
微服務架構能夠提供使每一個服務根據需要進行擴充套件的能力,並且將服務部署到與他們的資源要求更加匹配的例項。如果訂單服務需要根據需要進行擴充套件,他能夠在不需要對應用的其他元件服務進行擴充套件的情況下實現。如果配置服務需要更多的記憶體,只需要簡單的將它部署到記憶體更多的例項上即可。它仍然能夠將多個服務部署到相同的例項,但是我們有能力在我們的部署中更好的優化成本和規模。
不同的技術堆疊和衝突的依賴性
單體應用通常使用一種開發語言,在一種技術堆疊之上進行開發,經常會基於堆疊的特定版本。如果應用的一個元件希望使用技術堆疊的最新版本中的新特性,可能會因為應用中其他元件無法支援而不會去採用它。所以,在單體應用中,對更先進的技術的利用會嚴重的滯後。
使用微服務架構的應用是由獨立的服務組成的,這些服務可以使用不同框架、不同版本的庫,甚至完全不同的作業系統平臺。這就可以讓開發人員選擇最合適的技術來實現功能特性,避免功能特性和庫之間技術堆疊版本的衝突。
比如,圖1中的配置服務可能會採用Java進行實施,使用到Elastic Search特性;同時訂單服務使用Node.js,並且使用強一致性和報告特性的事務型資料庫,比如Oracle資料庫。開發人員甚至可以使用同一種語言的不同版本或者技術堆疊進行服務的開發,不需要擔心依賴衝突。
使用微服務時的注意事項
在微服務架構帶了很多好處的同時,你需要認識到的很重要的一點,你正在進入分散式計算的世界。分散式計算總是一個複雜的課題,微服務也不例外。在開始使用微服務時,有幾件事你需要注意到。
複雜性增加
在微服務架構中,有很多可移動的元件,所以對服務的管理將變得更加複雜。相比於單節點應用的部署,你要部署成百上千的服務,還要讓它們在一起無縫的工作。這需要服務註冊和服務發現解決方案,以便一個新的或者更新的服務能夠讓自己被系統知道,能夠被其他服務檢測到。你也需要確保所有的服務都啟動並且在運行當中,沒有耗盡磁碟空間或者其他資源,並且保證足夠的效能。所有的服務通常都會需要負載均衡,並且使用同步或者非同步的訊息傳送來進行通訊。叢集管理和編排工具會幫助你解決一些問題,但是也需要你瞭解這些工具是如何進行工作的。在這系列部落格的第二部分,我們將更深入的瞭解叢集管理和編排如何幫助微服務進行工作的。
網路擁塞和延遲
微服務用來通訊的API使用的是標準協議,比如HTTP,所以網路成為重要因素。想象一下在一個應用中有數百個服務,通常一個請求就會跨多個不同的服務,不難看出,如果網路方面沒有給予足夠的重視的話,將會對應用的整體效能造成多大的影響。另一個經常被忽略的地方是資料的序列化和反序列化。有時,相同的資料從一個服務傳遞到另一個服務,它會被序列化和發序列化多次,從而大大增加了網路的延遲。有幾種模式可以使用,比如資料快取和服務,來限制請求的數量。對於序列化問題,你可以使用高效的序列化格式,並且在整個服務框架中使用這個共用的格式。這可能會在服務間傳遞資料時減少一些步驟,不需要再次序列化。
資料一致性
因為每一個微服務通常都會有它自己的狀態儲存,所以你必須要面臨分散資料所帶來的資料一致性和完整性挑戰。考慮下面的場景,訂單服務所引用的資料在另一個服務當中,比如產品目錄服務,你就需要維護該服務中的資料完整性。現在你在每個服務中都有一些相同的資料,必須要保證一致性;如果一個服務節點中的資料變更,其他節點中的資料必須一起進行變更。如果在產品目錄服務中的資料被刪除或者更新,比如有效產品項的數量,訂單服務就需要知道這種變化。處理這種一致性挑戰,以及諸如此類的資料一致性概念,可能很難得到正確的結果,但是幸運的是,這個問題已經被解決了。比如,你可以使用事件源或者通知服務之類的模式,將變化的資料釋出給已經訂閱這種變化和更新的資料消費服務。
容錯和彈性
微服務應用的特性之一是,即便在發生災難性故障時,它仍能夠實現容錯。由於在網路中存在很多微服務,因此,在微服務架構中,故障也更為普遍,也更具挑戰性。你可能想知道,這是怎麼發生的呢?因為微服務通常都執行在它們自己的程序或者容器當中,其他的微服務是不會直接影響到它的程序的。所以,一個壞的微服務怎麼會擊倒整個應用?我們來看個例子,如果一個微服務花費太長時間來進行相應,在服務呼叫中耗盡所有的執行緒資源,它就會引起整個呼叫鏈的級聯故障。對故障進行合適的處理,也會對應用正常執行時間的SLA產生影響。我們假設你的應用需要有99.9%的正常執行時間的SLA,也就是說每個月只允許大約44分鐘的停機。你的應用包含3個微服務,每個都提供99.9%的正常執行時間。每一個服務都有可能在不同的時間出現停止服務,你就會看到潛在的停機時間大約是132分鐘,明顯影響了整個應用正常執行時間的SLA。
要進行故障處理,讓你的應用實現容錯,你需要實現彈性模式,比如超時、重試、熔斷機制和隔離機制,這對於開發人員來說都是非常具有挑戰性的。
診斷
在微服務應用中,日誌和追蹤需要一個合理的策略。需要對日誌聚合和分析進行認真的思考,因為微服務應用中有成百上千個服務,生成了大量的日誌。此外,請求通常會跨越多個服務,所以,找到一種方法在整個系統中對請求進行標記非常重要,讓你能夠看清跨越所有服務的整個請求。這通常都是通過使用關聯或者傳遞給所有下游服務的活動ID來實現的,每一個服務都會將這個ID寫入它的日誌。由於服務是由不同的團隊開發的,所以確定一種統一的日誌格式也很重要。微服務應用的總體診斷與除錯是很有挑戰性的,必須在一開始就計劃好。在本系列的第三部分,我們將介紹一些診斷的最佳實踐。
版本控制
在單體系統中,呼叫一個介面的程式碼通常與介面的實現部署在一起。介面的中斷變更通常是在整合測試或者構建期間被捕獲。在微服務世界中,一個微服務介面的變更不需要呼叫它的微服務立即進行處理,因為他們可能有不同的釋出節奏。為了保證呼叫服務仍然能夠按照預期進行工作,需要整個團隊考慮並且認可服務版本控制技術。
DevOps
現金的DevOps,自動化和監控是微服務運營成功的關鍵。在生產環境中進行測試通常是一個目標,實現這個目標需要更多的強調監控,使我們能夠快速的檢測到異常和問題,並且根據需進行回滾。在自動化方面進行投資,使用諸如Blue-Green Deployment、Canaries、A/B Testing和特性標誌等工具和最佳實踐,非常重要。建立起一個定義良好的工作流,讓開發和運營一起工作,帶來敏捷、高質量的釋出,非常有挑戰性。本系列部落格的第三部分將對DevOps的流程進行更詳細的介紹。
總結
本文中我們介紹了使用微服務所帶來的好處,解釋了為什麼微服務對很多企業有如此的吸引力。我們也介紹了基於微服務應用所帶來的一些挑戰。後續,我們將更詳細的介紹如何應對這些挑戰。下一部分,我們將介紹如何使微服務與容器一起工作,在微服務的世界裡,諸如Kubernetes之類的角色編排和容器管理工具是如何工作的。