創建微服務?請先回答這10個問題

jopen 8年前發布 | 14K 次閱讀 微服務

乍一看微服務似乎很容易構建,但是要真正構建微服務,要完成的工作可比在容器里運行一些代碼,并在這些代碼間使用HTTP請求進行通信,要多得多。在開發新的微服務之前——必須得在新服務部署到生產環境之前——你需要回答下面這10個重要的問題。

1. 如何測試服務?

當考慮到測試時, 微服務 有一些優勢和劣勢。一方面,定義良好的一小段功能的小型服務的單元測試,要比測試整個大型應用程序容易得多。另一方面,要驗證由很多微服務組成的整個應用程序的質量,則必然會顯著加大測試的復雜度:無法運行單個命令來測試一個進程里的代碼,大量集成的互相依賴的組件必須首先運行起來,才能驗證其健康狀況,并且需要在測試過程中一直保持其運行。

新的微服務是否既會進行隔離測試(使用單元測試或模擬依賴),也會連接到一些生產環境里實際會連接的服務上,在更貼近實際使用情況的“集成”或者“過渡”環境里進行測試?測試是否會合并性能驗證和錯誤模式?是否所有測試都會自動化,或者需要人為干預測試的運行以及測試結果的查看?要讓微服務可以簡單,快速,并且自動化地進行測試,這鼓勵開發人員維護測試,并且避免“ 破窗 ”問題。

2. 如何配置服務?

一旦新的微服務部署到生產環境里,如何才能影響其內部行為?這里包括基礎架構的改動(比如,在資源池里改變最小進程數),以及一些應用程序級別的改動(比如,通過觸發 特性標志 來啟動新特性)。對于這所有的改動,要重點注意讓這些改動生效是否需要重啟服務。

3. 系統的其他部分如何使用該服務?

除非系統的其他組件的確需要使用某個服務,才有必要構建它,因此理解它們會如何使用該服務至關重要。

其他組件和這個新服務的交互是同步還是異步的?是否鼓勵它們緩存來自該服務的響應?怎樣重試并且保證結果的 冪等性 ?新的微服務的在線時間的SLA是否匹配系統的其他組件?

需要清晰定義這個新的微服務所能夠提供的響應延遲,調用該服務的組件必須知道這些指標。這樣,當沒有達到這些指標時,系統的其他部分才能夠決定發出超時信號,中斷當前操作,或者轉到服務的另一個實例上。

4. 如何保護該服務?

除非在一個要求高度安全的環境里,大部分部署在防火墻后的微服務不需要過多操心服務內的安全性。在微服務之間添加大量的安全檢查會帶來巨大的操作復雜度,并且使得生產環境問題更難調試和修復。即使為服務內通信使用HTTP之上的HTTPS都會因為要求維護,部署以及保護一些正確簽名的證書,而帶來大量維護上的額外開銷。

通常的方案是讓流量在微服務間暢行無阻,同時使用應用程序級別的授權和認證,這樣來保證應用程序級別的安全。

因此,系統里的其他組件應該能夠給微服務發送請求,但是可能仍然需要同時傳遞一些認證數據,這些數據代表實際被批準的該請求最初的外部用戶。這些數據永遠不能是明文密碼數據,可以使用類似 JWTOAuthSAMLAuth0 這樣的技術。不管使用哪種方案,都需要清晰記錄所用技術,最好包含在客戶端庫或者示例代碼里,從而讓其他開發人員能夠輕松使用這個新的微服務。

5. 如何發現服務?

當新的微服務啟動后,系統里的其他組件如何發現它?發現服務的流程越簡單,可能的復雜度就越小,但是之后面臨的問題就會越多。比如,最簡單的方法(當然也很容易出錯)就是在其他依賴于該服務的組件代碼或者配置里硬編碼微服務的地址。這樣確實能夠工作,直到服務地址發生變動,或者直到在其他域里啟動了該服務的多個實例。這顯然不是推薦的方式。

使用間接技術,比如DNS名稱,能夠一定程度上更好地隱藏微服務的地址,但是這樣的方案也有自身的缺陷:找到一個合適的TTL值,強制重做名稱解析,保證DNS緩存行為一致,等等。從設計上看,DNS并沒有考慮服務的可用性,這會使得應用程序的組件將請求發送到一個無人偵聽的IP地址,會很浪費時間,并且因為嘗試找到能夠工作的實例而干擾到實際的運營。這也會讓開發人員的體驗非常糟糕,因為使用DNS作為路由機制通常會導致開發人員需要頻繁修改其/etc/hosts文件。

最復雜的方案里,高可用的數據庫和數據同步服務(比如ZooKeeper)可能會用作當前可用并且工作良好的微服務的注冊處。這樣的方案要求更多的技術投資,并且需要小心處理,保證發現服務本身不會成為單點故障點(Single Point of Failure,SPOF)。微服務啟動時,會將自身注冊到這樣的注冊服務里,微服務關閉時則會將自身移除。如果微服務意外終止或者死鎖了,它們也會被自動地從注冊處移除。記住,發現服務并不僅僅是找到什么在運行——知道什么不可用也非常重要。

6. 負載增加時服務如何擴展?

如果某個微服務在應用程序里的確很有價值,那么使用其的開發人員會不斷增加,隨著使用的增長,流量會激增。新的微服務有設計良好的擴展計劃,這對于運營團隊非常重要。

微服務是否能自動擴展?是否有狀態駐留在內存里,導致自動擴展和請求路由很困難(比如,用戶會話狀態)?如果有的話,分區策略是什么?

如果能事先了解大幅擴展時微服務的哪個部分會首先出錯會很有用。對于由數據庫支持的服務而言,計算能力(比如,位于自動擴展組里的EC2實例)通常能夠持續擴展直到數據庫不堪重負。對于真正的無狀態服務而言(比如,不從數據庫讀取也不寫入的計算型微服務),首先會出問題的可能是位于實例集群之前的負載均衡器。這兩種情況都有對應的解決方案,不過在部署微服務的第一個版本時,這些方案并不一定需要就位。但是,需要詳細了解新的微服務的限制,這樣才能在生產環境能力達到上限之前就知道服務擴展的天花板位于何處。

7.該服務如何處理其依賴錯誤?

即使微服務的范圍非常小,它也可能依賴于系統里已有的其他服務或者monolith程序。比如,大部分應用程序事務需要查看客戶信息,因此用來訪問客戶記錄的服務通常是提供業務價值的大部分服務的依賴。

如果新的微服務依賴于任何其他服務,當這些依賴服務故障時會發生什么至關重要。使用固定的請求超時時間是個好的開始,但是添加流程斷點可能會更好。所依賴服務的所有者應該也希望其使用者在故障發生時使用類似指數延遲的技術,來避免 驚蟄問題 的發生。

這種場景很好測試,因為其測試只需要所依賴服務不可用即可。但是,務必記住所依賴服務API的調用失敗可能會有 很多種原因 ,這些故障表現也各不相同。

8. 系統的其他部分如何處理該新服務的故障?

取決于在新微服務的高可用能力上投資多少,也取決于其支持何種事務,這可能并不是個重要的問題。比如,一個簡單的運營日志微服務,通過UDP異步發送數據,可能出現幾分鐘的故障,但是這對于應用程序的主要業務事務并沒有任何影響。但是,異步處理信用卡事務的微服務如果發生故障,則可能嚴重損壞電子商務系統,那么這種故障場景就必須嚴格測試,并為之做好應對準備。

因此,即使范圍有限的微服務(或者其開發人員)不需要擔心系統的其他部分如何使用這個新組件,系統級別上關于每個服務如何依賴于其他服務的考量能夠幫助避免連鎖故障,也能幫助確保應用程序的整體性能。

9. 該服務如何升級?

可能大家傾向于認為Docker這樣的容器技術,和Ansible這樣的部署自動化工具使得升級變得不那么重要,但是微服務的維護需要考慮很多這些已有工具無法解決的其他方面的問題。

定義升級策略,并且決定微服務支持的部署復雜度級別十分重要。想用新版本取代舊版本時, canary測試藍/綠部署 ,特性標志,以及 response diff'ing 這些,比起簡單的滾動升級而言,要求更多的時間和投入。

為微服務API的升級定義界線和策略對于依賴于其的組件更為重要。比如,一次只允許某個API的JSON schema添加一個改動,這樣使得服務能夠持續改進,并且不要求其使用者每次都必須隨之升級。但是,向XML響應負載里添加新字段時,如果其使用者每次都做XML schema驗證的話就會導致嚴重的問題。因此如果規律升級新的微服務,向其API對象添加越來越多的字段,那么需要在其文檔里清晰記錄,告知其服務的使用者。

最后,要了解如果新版本有問題時,微服務如何回滾,以及如何考慮“回滾判斷指標”。

10.如何監控并度量服務?

如果你的公司已經有了應用程序監控的標準,那么就應該使用這些標準,借助已有的監控生態系統。注意不能忽略已有標準——或者更為嚴重地——使用新的監控工具而運營團隊之前完全沒有使用過。

如果你的公司還沒有高質量的應用程序監控系統,向應用程序添加新的微服務可以作為推動監控系統搭建的起點。這對于之前都是監控大型monolithic應用程序,現在才開始向微服務架構遷移的企業來說尤其重要:一系列互相連接的微服務的運營監控需求要比單個大型的monolith程序的監控需求復雜得多。

無論選擇哪種監控方案,是自己開發,選擇開源軟件還是商業軟件,微服務的開發人員都應用能夠完全訪問其組件的監控和度量數據。如果缺失這樣的透明度,那么就無法實現完整的反饋回路,開發人員就無法知道如何在生產環境里改進其服務,也無法在發生問題時幫助快速診斷出問題所在。

總結

并不要求大家對上述10個問題的每一個都有特別詳細的答案,但是需要對每點都加以考慮,并且知道微服務可能會帶來的架構上的限制。比如,一開始新的微服務部署時可能并沒有考慮災備和域故障容忍,隨后升級來包含這樣的能力。了解微服務當前能做什么,不能做什么至關重要,思考上述問題的答案能夠幫助持續改進服務,最終演進成為成熟的,彈性的,可靠的系統組件。

原文鏈接: Creating a Microservice? Answer these 10 Questions First (翻譯:崔婧雯 校對:)

===========================

譯者介紹

崔婧雯,現就職于IBM,高級軟件工程師,負責IBM WebSphere業務流程管理軟件的系統測試工作。曾就職于VMware從事桌面虛擬化產品的質量保證工作。對虛擬化,中間件技術,業務流程管理有濃厚的興趣。

來自: http://dockone.io/article/1018

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!