【51CTO.com快譯】本文將介紹一些微服務的優秀實踐,并提出幫助開發人員設計、編排和保護微服務架構的一些方法。通過了解這些實踐,將為開發人員成功開發項目提供幫助。
微服務的好處和挑戰
在深入研究微服務優秀實踐之前,應該首先了解微服務的好處和挑戰,以及為什么要使用它們的原因。
簡而言之,微服務是一種改進的軟件架構,可以讓開發人員:
- 更快地部署和擴展。更小的應用程序域允許自動化,從而實現更快的部署和更快的擴展。
- 減少停機時間。限制不可用服務對主要業務功能的影響,從而提高其整體業務的正常運行時間。
- 確保可用性。使微服務之間的功能保持離散,從而限制實例宕機時的影響。
當然采用微服務擁有這些好處,也會面臨著一系列新的挑戰,其中包括服務間通信、安全性和可擴展性。
- 服務間通信。對于單體應用來說,所有模塊都可以固有地相互通信。因此需要管理一個證書,一旦請求經過身份驗證和授權,就可以毫無問題地遍歷代碼路徑。當開發人員從單體架構中提取一個功能到微服務應用程序時,曾經的內部函數調用變成了需要對這個外部微服務進行身份驗證和授權的外部API調用。
- 安全層。認證和授權在單體應用中,可以在入口處一次性處理。隨著向微服務的過渡,每個微服務都需要執行一些身份驗證和授權以強制執行訪問控制。但是要求用戶每次使用不同的微服務都要進行登錄是不現實的,因此需要建立一個全面的認證策略。
- 可擴展性。盡管微服務允許開發人員快速擴展獨立功能,但要有效地做到這一點,需要良好的應用程序管理甚至更好的工具。可擴展性的有效性取決于開發人員的微服務編排平臺,以下將更詳細地進行討論。
微服務的優秀實踐
在對微服務的好處和挑戰的快速概述之后,以下深入研究微服務的一些優秀實踐。這些優秀實踐將幫助開發人員創建一個強大、易于管理、可擴展且安全的互通微服務系統。
1.較小的應用程序域
采用微服務策略需要遵循單一職責原則。通過限制單一服務的責任范圍,可以降低該服務失敗的負面影響。如果單個微服務的責任太多,發生故障或不可用將對系統的其余部分產生多米諾骨牌效應。
顧名思義,微服務是微小的服務,而保持微服務的應用程序域很小,可以專用于一項邏輯功能。如果出現任何問題,這將減少特定的微服務的影響。此外,較小的服務更易于維護,其結果是更容易更新和更快的開發。
那么這在實踐中是什么樣子的?例如,假設微服務是一個API服務器,它接受獲取數據的請求,并且這些請求必須附帶一個授權令牌。在剛開始時,這是唯一需要授權令牌的微服務。為什么不將身份驗證和令牌生成作為微服務的一部分?乍一看,其優點是活動部件少,管理工作少。
當然,開發人員如果擁有需要授權令牌的其他服務,則很快就會發現原來的微服務將充當API服務器和身份驗證服務器。如果API服務器宕機,那么其身份驗證服務器也會隨之宕機。這樣,所有其他需要授權令牌的服務也是如此。
因此考慮未來的發展,開發人員需要保持微服務的微小化。
2.數據存儲分離
連接到同一個數據庫的多個微服務本質上仍然是一個單體架構。單體應用只是運行在數據庫層而不是應用層,這使得它同樣脆弱。每個微服務都應該盡可能地擁有自己的數據持久層。這不僅確保了與其他微服務的隔離,而且如果特定數據集變得不可用,還可以最大限度地減少影響范圍。
有時,不同的微服務訪問同一數據庫中的數據似乎是有意義的。然而,更深入的研究可能會發現,一個微服務僅適用于數據庫表的子集,而另一個微服務僅適用于完全不同的數據庫表子集。如果這兩個數據子集是完全正交的,那么這將是將數據庫分離為單獨服務的一個很好的例子。這樣,一個服務依賴于其專用數據存儲,并且該數據存儲的故障不會影響除該服務之外的任何服務。
以文件存儲為例。在采用微服務架構時,不需要單獨的微服務使用相同的文件存儲服務。除非有實際的文件重疊,否則單獨的微服務應該有單獨的文件存儲。
這種數據分離提高了靈活性。例如,假設有兩個微服務都與云計算提供商共享相同的文件存儲服務。其中一個微服務經常接觸大量文件,但這些文件很小,而另一個微服務只有幾個定期訪問的文件,但這些文件的大小很大,達到數百GB。
對這兩個微服務使用通用的文件存儲服務將會降低優化成本的靈活性,這是因為同時擁有大文件和小文件以及定期訪問的混合。如果每個微服務都有自己的數據持久層(當然可以是一個單獨的微服務),那么就可以更靈活地找到更適合該單個微服務需求的提供者或服務。
成本優化、選項的靈活性以及對可能失敗的單一解決方案的更少依賴,這些都是分離不同微服務數據的原因。
3.溝通渠道
微服務之間如何溝通需要深思熟慮,特別是在關注的事件方面。否則,單個不可用的服務可能導致通信中斷,并可能導致整個應用程序崩潰。
例如在一個在線商店的微服務系統中,一個微服務接受在網站下的訂單;另一個微服務向客戶發送一條文本通知,告知收到了他們的訂單;第三個微服務通知倉庫發出產品。最后,第四個微服務更新庫存計數。
微服務之間有兩種通信方式:同步和異步。如果使用同步通信來處理上述示例,Web服務器可能會通過首先向客戶通知服務發送請求來處理新訂單。客戶通知服務在得到響應之后,Web服務器向倉庫通知服務發送請求,然后再次等待響應。最后,Web服務器向庫存更新程序發送請求。這個同步方法如圖1所示:
圖1 微服務之間的同步通信
當然,在客戶通知服務發生故障情況下,通知客戶的請求可能會超時或返回錯誤,或者可能讓Web服務器無限期地等待響應。那么倉庫通知服務可能永遠不會收到發送請求。而微服務之間的同步通信可以創建一個依賴鏈,如果鏈中的任何連接中斷,該鏈就會中斷。
在異步通信中,服務發送請求并在不等待響應的情況下繼續發送。在一種可能的異步方法中,Web服務器可能會發送“通知客戶”請求,然后完成其任務。客戶通知服務負責通知客戶并向倉庫通知服務發送異步請求,倉庫通知服務負責向庫存更新服務發送請求。這個示例如圖2所示:
圖2 微服務之間的鏈式異步通信
當然在這個模型中,看到異步通信仍然會產生依賴鏈,單個服務的故障仍然會中斷應用程序。
異步通信的一種簡單但有效的方法是采用發布/訂閱模式。當感興趣的事件發生時,生產者(在本例中為微服務)將該事件的記錄發布到消息隊列服務。對此類事件感興趣的任何其他微服務作為該事件的消費者訂閱消息隊列服務。微服務只與消息隊列服務交談和監聽,而不是彼此通信。
這個示例如圖3所示:
圖3 消息隊列服務促進異步通信
消息隊列是一個獨立的服務,與所有微服務分離。它負責接收已發布的事件并通知訂閱者發生的這些事件。這確保了一個微服務的故障(可能意味著消息延遲傳遞),但對其他相關但不關心的服務的影響最小。
有很多工具可以完成這種異步通信(例如Kafka或RabbitMQ)。因此需要尋找將這些工具集成為微服務異步通信主干的方法。
在有些情況下,微服務之間需要同步通信。大多數請求-響應交互出于必要是同步的。例如,查詢數據庫的API服務器必須等待查詢響應;獲取緩存數據的Web服務器必須等待鍵值存儲響應。
當需要同步通信時,開發人員需要使用開源Kong Gateway來確保其通信快速可靠地路由到正確的微服務。
4.兼容性
盡可能保持向后兼容性,這樣消費者就不會遇到損壞的API。實現這一點的常用方法是遵循路徑級兼容性保證,如/api/v1或/api/v2。任何向后不兼容的更改都會轉到新路徑,如/api/v3。
然而,盡管開發人員作為軟件工程師盡了最大的努力,但有時還是需要棄用API,所以不會一直運行它們。使用API網關請求轉換插件,其微服務可以通過在原始API響應旁邊輕松注入棄用通知或附加類似于Kubernetes的“棄用標頭”來提醒API使用者。
5.編排微服務
微服務的編排是流程和工具成功的關鍵因素。從技術上講,開發人員可以使用systemd和Docker或podman之類的東西在虛擬機上運行容器,但這無法提供與容器編排平臺相同級別的彈性。這會對采用微服務架構帶來的正常運行時間和可用性優勢產生負面影響。對于有效的微服務編排,開發人員需要依賴經過實戰考驗的容器編排平臺;該領域的領導者顯然是Kubernetes。
Kubernetes管理所有容器的配置和部署,同時處理負載平衡、擴展、高可用性副本集和網絡通信問題。
開發人員可以在本地部署Kubernetes,也可以在Azure Kubernetes Service、Red Hat OpenShift或Amazon Elastic Kubernetes Service中使用。Kubernetes內置的調度、復制和網絡功能使微服務編排比在傳統操作系統上容易得多。
將Kubernetes與Kuma服務網格和Kong Ingress Controller結合使用,就創建了可發現、受監控且具有彈性的微服務。
6.微服務安全
隨著應用程序包含越來越多的微服務,確保適當的安全性可能會變得復雜。用于執行安全策略的集中式系統對于保護應用程序免受惡意用戶、黑客和錯誤代碼的侵害至關重要。無論是在虛擬機上還是在Kubernetes上運行,Kong都應該是開發人員使用微服務的安全故事的開始。Kong維護的大量安全插件可以輕松滿足微服務的一些最常見的需求,其中包括身份驗證、授權、流量控制和速率限制。
示例:使用Kong Ingress Controller進行速率限制
為了演示工作中的安全插件示例,將部署Kong的速率限制(Rate Limiting)插件,以展示Kong如何防止對應用程序的過多入站請求。將使用kind創建一個本地Kubernetes集群,然后按照以下說明部署Kong Ingress控制器。
在創建集群并部署Kong Ingress Controller之后,第一步是設置速率限制插件。可以為不同的范圍設置插件。將使用Kubernetes集群上的默認項目作為用例,并將插件范圍限定為默認命名空間。
然后為該服務創建一個“echo服務”和一個入口。在本例中,采用了Kong的Kubernetes Ingress控制器入門文檔中的示例:
需要做的最后一件事就是測試,將從Kubernetes文檔中借用shell-demo進行集群內測試:
在進入shellpod之前,需要kong-proxy的集群IP:
現在,可以通過shell訪問的pod并測試速率限制:
大多數云計算提供商不需要使用中間pod來測試速率限制的額外步驟,這為開發人員提供了開箱即用的負載均衡器。在這種情況下,由于使用的是kind,因此沒有配置負載均衡器,而這個測試來自集群內部。如果有可用的負載平衡器,同樣的測試也可以在外部進行。
速率限制只是一個例子,說明Kong能夠滿足整體微服務戰略和優秀實踐的安全考慮,并且可以輕松提供全面的解決方案。Kong維護多個插件和產品,以使通信渠道萬無一失、API更改影響最小化,并使應用程序域易于管理。另外,它與大多數編程語言和供應商選項兼容。
7.指標和監控
基于微服務的架構可能導致數百或數千個小型模塊化服務的大規模擴展。盡管這為提高速度、可用性和覆蓋范圍帶來了巨大潛力,但一個龐大的微服務系統需要一種戰略性和系統性的監控方法。通過密切關注所有的微服務,將確保它們能夠正常運行,對用戶可用,并正確使用資源。當這些期望中的任何一個沒有得到滿足時,可以采取適當的行動來應對。
如今有多種廣泛采用的監控解決方案可以無縫集成到基礎設施中。一些解決方案使用指標導出器SDK,可以通過在微服務中添加一兩行代碼來集成。其他的可以作為插件與API網關或服務網格集成,用于監控網絡問題和資源使用情況。
通過監控微服務并清楚地顯示數字,可以就如何保持微服務的健康運行和可用性做出明智的決策。在這樣做時,將會讓用戶感到滿意。
采用監控工具收集指標時,可視化工具和儀表盤可以使用這些指標,幫助查看微服務背后的數字。例如,上周三晚上8點有多少用戶在線?自從發布這個新特性以來,CPU負載增加了多少?產品發貨API和發票API之間的延遲是多少?
結語
微服務是一個令人興奮的旅程。企業在開始時從更快的部署和可擴展性、減少停機時間以及全面提高業務可用性獲得令人難以置信的好處。然后再加入編排平臺,以及一些由Kong及其插件支持的優秀實踐,以上只介紹了Kong所能做的一小部分,因此強烈建議查看Kong Hub所有可用的功能,以簡化微服務之旅。
原文標題:7 Microservices Best Practices for Developers,作者:Michael Bogan
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】