實用 具有Spring Cloud和 Docker 的微服務架構

如何使用Spring Boot,Spring Cloud,Docker和Netflix的一些開源工具設置微服務架構。

本文以使用Spring Boot,Spring Cloud和Docker構建的概念驗證應用程序爲例,爲了解常見的微服務架構模式提供了一個起點。

該代碼在Github上可用,圖像在Docker Hub上可用。你只需一個命令即可啓動整個系統。

作爲該系統的基礎,我選擇了一箇舊項目,該項目的後端曾經是一個整體。該應用程序提供了一種處理個人財務,組織收入和支出,管理儲蓄,分析統計數據以及創建簡單預測的方法。

功能服務
整體應用程序被分解爲三個核心微服務。它們都是圍繞某些業務功能組織的可獨立部署的應用程序。
在這裏插入圖片描述
開戶服務
包含常規用戶輸入邏輯和驗證:收入/支出項目,儲蓄和帳戶設置。
在這裏插入圖片描述

統計服務
對主要統計參數執行計算,並捕獲每個帳戶的時間序列。 數據點包含標準化爲基礎貨幣和時間段的值。此數據可能用於跟蹤帳戶生命週期中的現金流量動態。
在這裏插入圖片描述

通知服務
存儲用戶的聯繫信息和通知設置(如提醒和備份頻率)。計劃工從其他服務收集所需的信息,並將電子郵件發送給訂閱的客戶。

在這裏插入圖片描述

筆記
每個微服務都有自己的數據庫,因此無法繞過API並直接訪問持久性數據。
對於這個項目,我使用MongoDB作爲每個服務的主數據庫。 擁有多語言持久性體系結構(選擇最適合服務需求的數據庫類型)也可能是有意義的。
服務到服務的通信已大大簡化:微服務僅使用同步REST API進行通話。 實際系統中的常見做法是使用交互樣式的組合。 例如,執行同步GET請求以檢索數據,並通過Message Broker使用異步方法進行創建/更新操作,以使服務和消息緩衝脫鉤。 但是,這使我們進入了最終的一致性世界。

基礎設施服務
分佈式系統中有一堆常見的模式,可以幫助我們使描述的核心服務正常工作。 Spring Cloud提供了強大的工具,這些工具可以增強Spring Boot應用程序的行爲以實現這些模式。我會簡單介紹一下。
在這裏插入圖片描述
配置服務
Spring Cloud Config是用於分佈式系統的水平可擴展集中式配置服務。 它使用了當前支持本地存儲,Git和Subversion的可插入存儲庫層。
在此項目中,我使用本機配置文件,該配置文件僅從本地類路徑加載配置文件。你可以在配置服務資源中看到共享目錄。 現在,當Notification-service請求進行配置時,Config服務將使用shared / notification-service.yml和shared / application.yml(在所有客戶端應用程序之間共享)進行響應。

客戶端使用
只需使用spring-cloud-starter-config依賴關係構建Spring Boot應用程序,其餘的工作就由自動配置完成。

現在,你在應用程序中不需要任何嵌入式屬性。 只需爲bootstrap.yml提供應用程序名稱和配置服務網址即可:

spring:
  application:
    name: notification-service
  cloud:
    config:
      uri: http://config:8888
      fail-fast: true

藉助Spring Cloud Config,你可以動態更改應用程序配置

例如,EmailService bean用@RefreshScope註釋。這意味着您可以更改電子郵件文本和主題行,而無需重建和重新啓動Notification Service應用程序。
首先,在Config服務器中更改所需的屬性。然後,對通知服務執行刷新請求:curl -H“ Authorization:Bearer#token#” -XPOST http://127.0.0.1:8000/notifications/refresh
你也可以使用webhooks自動執行此過程。

筆記
儘管如此,動態刷新還是有一些限制。@RefreshScope不適用於@Configuration類,並且不會影響@Scheduled方法。
``快速故障’'屬性意味着Spring Boot應用程序無法連接到Config Service時將立即啓動失敗。當你一起啓動所有應用程序時,這非常有用。
下面有重要的安全說明。

驗證服務
授權職責已完全提取到單獨的服務器中,該服務器爲後端資源服務授予OAuth2令牌。Auth Server用於用戶授權以及外圍內部安全的機器對機器通信。
在此項目中,我將密碼憑據用作用戶授權的授予類型(因爲它僅由本機應用程序UI使用),並將客戶端憑據用作微服務授權的授予類型。
Spring Cloud Security提供了方便的批註和自動配置,以使從服務器和客戶端兩者都真正易於實現。你可以在文檔中瞭解更多信息,並在Auth Server代碼中查看配置詳細信息
從客戶端來看,所有工作都與傳統的基於會話的授權完全相同。你可以從請求中檢索主體對象,使用基於表達式的訪問控制和@PreAuthorize註釋檢查用戶角色和其他內容。
PiggyMetrics中的每個客戶端(帳戶服務,統計服務,通知服務和瀏覽器)都有一個範圍:服務器用於後端服務,服務器ui用於瀏覽器。 因此,我們還可以保護控制器免受外部訪問,例如:

@PreAuthorize("#oauth2.hasScope('server')")
@RequestMapping(value = "accounts/{name}", method = RequestMethod.GET)
public List<DataPoint> getStatisticsByAccountName(@PathVariable String name) {
    return statisticsService.findByAccountName(name);
}

API網關
如你所見,有三個核心服務,它們向客戶端公開了外部API。在現實世界的系統中,此數字以及整個系統的複雜性都可以非常迅速地增長。實際上,渲染一個複雜的網頁可能涉及數百種服務。

API網關從理論上講,客戶端可以直接向每個微服務發出請求。但是顯然,此選項存在挑戰和侷限性,例如必須知道所有端點地址,分別對每個信息進行http請求,將結果合併到客戶端。另一個問題是非Web友好的協議,該協議可能在後端使用。

通常,更好的方法是使用API網關。它是系統的單個入口點,用於通過將請求路由到適當的後端服務或調用多個後端服務並彙總結果來處理請求。此外,它還可用於身份驗證,見解,壓力和金絲雀測試,服務遷移,靜態響應處理,主動流量管理。

Netflix開源了這種邊緣服務,現在藉助Spring Cloud,我們可以使用一個@EnableZuulProxyannotation啓用它。在這個項目中,我使用Zuul存儲靜態內容(UI應用程序)並將請求路由到適當的微服務。 這是通知服務的基於前綴的簡單路由配置:

zuul:
  routes:
    notification-service:
        path: /notifications/**
        serviceId: notification-service
        stripPrefix: false

這意味着所有以/通知開頭的請求都將被路由到通知服務。如您所見,沒有硬編碼的地址。Zuul使用服務發現機制來定位Notification服務實例以及電路斷路器和負載均衡器,如下所述。

服務發現
另一個衆所周知的體系結構模式是服務發現。它允許自動檢測服務實例的網絡位置,由於自動縮放,故障和升級,該服務實例可以動態分配地址。
服務發現的關鍵部分是註冊表。 我將Netflix Eureka用於該項目。 當客戶端負責確定可用服務實例的位置(使用註冊表服務器)並在它們之間進行負載平衡請求時,Eureka是客戶端發現模式的一個很好的例子。
使用Spring Boot,你可以通過spring-cloud-starter-eureka-server依賴性,@ EnableEurekaServer批註和簡單的配置屬性輕鬆構建Eureka Registry。
使用@EnableDiscoveryClient註釋和bootstrap.yml啓用客戶端支持,應用程序名稱爲:

spring:
  application:
    name: notification-service

現在,在應用程序啓動時,它將向Eureka Server註冊並提供元數據,例如主機和端口,運行狀況指示器URL,主頁等。Eureka從屬於服務的每個實例接收心跳消息。如果心跳在可配置的時間表上進行故障轉移,則該實例將從註冊表中刪除。

此外,Eureka還提供了一個簡單的界面,你可以在其中跟蹤正在運行的服務以及可用實例的數量:http:// localhost:878761
在這裏插入圖片描述
負載平衡器,斷路器和Http客戶端
Netflix OSS提供了另一套很棒的工具。

Ribbon
Ribbon是客戶端負載平衡器,它使您可以對HTTP和TCP客戶端的行爲進行大量控制。與傳統的負載均衡器相比,每次通過線路調用都不需要額外的躍點-您可以直接聯繫所需的服務。
開箱即用,它與Spring Cloud和Service Discovery本地集成。 Eureka Client提供了可用服務器的動態列表,因此Ribbon可以在它們之間進行平衡。
Hystrix
Hystrix是Circuit Breaker模式的實現,該模式可以控制通過網絡訪問的依賴項帶來的延遲和故障。主要思想是在具有大量微服務的分佈式環境中停止級聯故障。這有助於快速故障並儘快恢復-自我修復的容錯系統的重要方面。
除了斷路器控制之外,使用Hystrix,您還可以添加一個後備方法,如果主命令失敗,該方法將被調用以獲取默認值。
此外,Hystrix會針對每個命令生成有關執行結果和延遲的指標,我們可以使用這些指標來監控系統行爲。
Feign
Feign是一個聲明性HTTP客戶端,它與Ribbon和Hystrix無縫集成。 實際上,憑藉一個spring-cloud-starter-feign依賴性和@EnableFeignClients批註,您具有一整套完整的負載均衡器,斷路器和HTTP客戶端以及明智的現成默認配置。
這是來自帳戶服務的示例:

@FeignClient(name = "statistics-service")
public interface StatisticsServiceClient {
    @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    void updateStatistics(@PathVariable("accountName") String accountName, Account account);
}

你所需要的只是一個界面
你可以在Spring MVC控制器和Feign方法之間共享@RequestMapping部分
上面的示例僅指定了所需的服務ID-統計服務,這要歸功於通過Eureka的自動發現(但顯然你可以使用特定的URL訪問任何資源)

監控儀表板
在此項目配置中,每個帶有Hystrix的微服務都通過Spring Cloud Bus(帶有AMQP代理)將指標推送到Turbine。 Monitoring項目只是一個帶有Turbine和Hystrix儀表板的小型Spring引導應用程序。
讓我們看一下負載下的系統行爲:帳戶服務調用統計信息服務,它以不同的模擬延遲響應。 響應超時閾值設置爲1秒。

在這裏插入圖片描述

日誌分析
在嘗試確定分佈式環境中的問題時,集中日誌記錄可能非常有用。 Elasticsearch,Logstash和Kibana堆棧使你可以輕鬆搜索和分析日誌,利用率和網絡活動數據。我的其他項目中介紹了現成的Docker配置。

安全
高級安全配置超出了此概念驗證項目的範圍。爲了更真實地模擬真實系統,請考慮使用https和JCE密鑰庫來加密微服務密碼和Config服務器屬性內容(有關詳細信息,請參閱文檔)。

基礎設施自動化
部署微服務及其相互依賴關係,比部署整體應用程序要複雜得多。 擁有完全自動化的基礎架構非常重要。我們可以通過持續交付方法獲得以下好處:
隨時發佈軟件的能力。
任何構建都可能最終成爲發行版。
一次構建工件,根據需要進行部署。
這是在此項目中實現的簡單連續交付工作流程:
在這種配置下,Travis CI爲每次成功的Git推送構建標記的圖像。因此,Docker Hub上的每個微服務總會有一個最新映像,而舊映像則使用Git commit哈希標記。如果需要,可以輕鬆部署它們中的任何一個並快速回滾。

如何運行所有東西?

這真的很容易,我建議你嘗試一下。請記住,你將啓動8個Spring Boot應用程序,4個MongoDB實例和RabbitMq。 確保你的機器上有4 Gb RAM。通過網關,註冊表,配置,身份驗證服務和帳戶服務,你始終可以只運行至關重要的服務。

在你開始前
安裝Docker和Docker Compose。
導出環境變量:配置_服務_密碼,通知_服務_密碼,統計_服務_密碼,帳戶_服務_密碼,MONGODB _密碼

生產方式
在這種模式下,所有最新映像都將從Docker Hub中提取。 只需複製docker-compose.yml並點擊docker-compose up -d。

開發模式
如果你想自己構建映像(例如,對代碼進行一些更改),則必須克隆所有存儲庫並使用Maven構建工件。 然後,運行docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
docker-compose.dev.yml繼承了docker-compose.yml,還具有在本地構建映像並公開所有容器端口的更多可能性,以方便開發。

重要端點
本地主機:80-網關
localhost:8761-尤里卡儀表板
localhost:9000-Hystrix儀表板
localhost:8989-渦輪流(Hystrix儀表板的源代碼)
localhost:15672-RabbitMq管理

筆記
所有Spring Boot應用程序都需要已運行的Config Server才能啓動。 但是由於Spring Boot的快速故障屬性和restart:alwaysdocker-compose選項,我們可以同時啓動所有容器。 這意味着所有依賴容器將嘗試重新啓動,直到Config Server啓動並運行。
此外,所有應用程序啓動後,服務發現機制都需要一些時間。 在實例,Eureka服務器和客戶端在其本地緩存中都具有相同的元數據之前,客戶端無法發現任何服務,因此可能需要3個聽音。 默認聽音週期爲30秒。

喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術乾貨、職場趣事、海量面試資料等等
如果你對java技術很感興趣也可以交流學習,來加入防脫髮羣 907135806 共同學習進步。
不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代

文章寫道這裏,歡迎完善交流。最後奉上近期整理出來的一套完整的java架構思維導圖,分享給大家對照知識點參考學習。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java乾貨,以及項目可以拿去練手。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章