共計 6489 個字符,預計需要花費 17 分鐘才能閱讀完成。
如何理解 Spring Cloud 和 Docker 的微服務架構,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Spring Cloud 和 Docker 的微服務架構
功能服務
整體應用被分解成三個核心的微服務。這些微服務是圍繞某些業務功能進行組織,可獨立部署的應用程序。
服務間關系
Account Service(賬戶服務)
包含用戶的輸入邏輯和驗證:收入 / 支出,儲蓄和賬戶設置。
Statistics Service(統計服務)
對主要統計參數執行計算,并獲取每個帳戶的時間線。數據點包含標準化為基本貨幣和時間段的值。這些數據可用于追蹤賬戶一生中的現金流動態
保存用戶聯系信息和消息設置(比如提醒和備份頻率),定時器從其他服務器上收集所需的信息并通過 emial 發送給訂閱者。
注意
·每個微服務都有自己的數據庫,不能繞過微服務提供的 API 直接訪問微服務的持久化數據。
·這個例子中我采用 mongoDB 作為每個微服務的數據庫,用戶可以根據微服務的類型選擇合適的數據庫。
·微服務和微服務間的采用同步的 REST API 進行通信,通常的做法是采用交互風格進行通信,比如:通過同步的 GET 請求來檢索數據,通過 Message Broker 使用異步方法來創建 / 更新操作,以便分離服務和緩沖區消息,目標是實現最終一致性。
Infrastructure Services(基礎設施服務)
分布式系統中有許多共同的模式,可以幫助我們描述核心服務。spring cloud 提供了強大的工具以幫助 spring boot 應用實現這些模式,下面會做一些簡單的介紹:
Config Service(配置服務)
spring cloud config 是分布式系統中的集中式配置服務。
在這個項目中,我使用 native profile 從本地的 classpath 上加載配置文件,你可以在 shared 目錄下面查看 config service resources。比如:當 Notification-service 請求它的配置信息,配置服務會返回如下來兩個文件:shared/notification-service.yml 和 shared/application.yml(這個文件會被所有的應用共享).
Client-side Usage(客戶端使用)
只要用 spring-cloud-starter-config 依賴構建 Spring Boot 應用程序,其余部分將自動配置
應用中不需要其他任何內置的 properties,只需要提供一個 bootstrap.yml 文件,這個文件中需要包含當前應用的名字和 Config service 的 url
spring:
application:
name: notification-service
cloud:
config:
uri: http://config:8888
fail-fast: true
spring cloud config 支持動態修改 App 的配置信息,比如:在 EmailService bean 上添加 @RefreshScope 注解,這就意味著你可以修改 email 的正文和標題而不用重新編譯或者重啟 Notification service。具體操作如下:
1、修改 config server 上相關的屬性
2、對 Notification service 執行刷新請求:
curl -H Authorization: Bearer #token# -XPOST http://127.0.0.1:8000/notifications/refresh
也可以采用 webhooks 自動執行這個流程
注意
1、動態刷新有如下限制:@RefreshScope 注解無法在 @Configuration 類和 @Scheduled 方法上生效。
2、fail-fast 屬性意味著如果服務無法連接上 config service,則服務會在啟動期間立即失敗。這在一起啟動所有服務的時候十分有用。
Auth Service(鑒權服務)
授權職責完全提取到單獨的服務器,后者為后端資源服務授予 OAuth3 令牌。身份驗證服務器用于用戶授權以及在外圍進行安全的機器對機器通信。
在這個項目中,我使用密碼憑證作為用戶授權的授權類型(因為它只被本機應用程序 UI 使用),而客戶端憑證作為微服務授權的授權類型。
Spring Cloud Security 提供了便利的注釋和自動配置,使得從服務器和客戶端都可以輕松實現。您可以在文檔中了解更多信息,并查看 Auth Server 代碼中的配置詳細信息。
客戶端與傳統的基于 session 的權限驗證類似,你可以從 request 中獲取 Principal 對象信息,校驗用戶的角色,使用 @PreAuthorize 注解進行基于正則的訪問控制。
每個 client (account-service, statistics-service, notification-service 和 browser)都有一個 scope 屬性: server:后臺服務, ui: 瀏覽器,通過 scope 能防止 controller 被外部訪問:
@PreAuthorize(#oauth3.hasScope( server) )
@RequestMapping(value = accounts/{name} , method = RequestMethod.GET)
public List getStatisticsByAccountName(@PathVariable String name) {
return statisticsService.findByAccountName(name);
}
API Gateway
在這個例子中,存在三個核心服務,將外部 API 暴露給客戶端,但是在現實世界中,隨著系統復雜度的增加,核心服務數也會急劇增長。可能存在一個復雜頁面,渲染這個頁面需要調用上百個服務。
理論上,客戶端應該直接請求每一個微服務,但是這種方式存在很多挑戰和局限性,比如:客戶端需要了解所有微服務的地址,為每一個信息獨立地執行 http 調用,然后在客戶端 merger 這些信息。Another problem is non-web-friendly protocols, which might be used on the backend.
通常一個更好的實現方式是使用 API Gateway,它是一個進入系統的單入口,目的是將請求路由到合適的后臺服務或者調用多個后臺服務并將結果聚合返回給客戶端。API Gateway 也會被用來做權限驗證,監控,壓力測試,服務遷移,靜態響應處理和主動流量管理
在 Spring cloud 項目中可以通過 @EnableZuulProxyannotation 注解使用 Netflix 開源的項目 edge service,
在這個例子中我們使用 Zuul 存儲靜態內容(UI application),路由請求到合適的微服務上,下面是 Notification service 的路由配置:
zuul:
routes:
notification-service:
path: /notifications/**
serviceId: notification-service
stripPrefix: false
這個配置意味著所有以 /notifications 開頭的請求都會被路由到 Notification service,Notification service 地址并沒有硬編碼,Zuul 使用服務發現機制定位 Notification service 實例并實現訪問的負載均衡。
Service Discovery(服務發現)
通過服務發現能夠自動地確定服務實例的網絡位置(由于實例數擴展,實例失敗 / 更新,會導致服務實例的網絡地址發生變化)
服務發現的關鍵部分是服務注冊,在這個例子中我們使用 Netflix Eureka 實現這個功能,Eureka 是基于客戶端服務發現模式的一個好的例子,客戶端負責確定可用服務實例 (使用注冊服務器) 的位置和負載均衡請求。
在 Spring Boot 中,您可以使用 spring-cloud-starter-eureka-server 依賴項,通過 @EnableEurekaServer 注釋和簡單的配置屬性來構建 Eureka Registry。
客戶端支持需要使用 @EnableDiscoveryClient 注解和添加包含應用名稱的 bootstrap.yml 文件
spring:
application:
name: notification-service
在應用啟動的時候,它會在 Eureka Serve 中注冊,并提供相關的 meta-data 信息 (比如:host,port,健康檢查頁,主頁等)。Eureka 從微服務的每個實例接收心跳信息,如果在約定的時間內(可配置) 沒有接受到心跳信息,這個實例就會被注冊中心移除。
Eureka 提供了一個簡單的頁面,在這個頁面上你可以查看運行的微服務以及這些服務對應的實例
Eureka
Load Balancer, Circuit Breaker, and Http Client(負載均衡,斷路器以及 http Client)
Netflix OSS 提供了另外一套優秀的工具集
Ribbon
Ribbon 是一個客戶端的負載均衡器,可以通過它控制 HTTP 和 TCP client 請求,與傳統的負載均衡器相比,每個線上調用不需要額外的跳躍,你可以直接聯系所需的服務。
Eureka 本身與 Spring Cloud 和 Service Discovery 集成在一起,開箱即用,Eureka Client 提供了一個可用服務的動態列表,Ribbon 可以通過這個列表來實現負載均衡。
Hystrix
Hystrix 是熔斷器模式的實現,通過網絡訪問依賴關系來控制延遲和失敗。核心思想是在大量微服務的分布式環境中停止級聯失敗,這有助于系統盡快恢復。
除了提供熔斷器,Hystrix 還可以添加一個 fallback 方法,在主命令失敗的情況下返回默認值。
而且,Hystrix 為每個命令生成執行結果和延遲的度量標準,我們可以用它來監視系統行為。
Feign
Feign 是一個聲明式 HTTP 客戶端,與 Ribbon 和 Hystrix 無縫集成。實際上,通過一個 Spring-Cloud-Starter-Feign 依賴和 @EnableFeignClients 批注,您可以擁有一整套負載均衡器,斷路器和 HTTP 客戶端,并具有合理的隨時可用的默認配置。
下面是 Account Service 的一個列子:
@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);
}
上面的例子指定了所需的服務 id – statistics-service,依靠 Eureka 的自動發現
Monitor Dashboard
在這個項目配置中,搭載 Hystrix 的每個微服務都通過 Spring Cloud Bus(使用 AMQP 代理)向 Turbine 推送指標。Monitoring project 只是一個小型的包含 Turbine 和 Hystrix 儀表板的 Spring boot 應用程序。
讓我們看看不同負載下的系統行為:Account service 調用 Statistics service,Statistics service 響應模擬不同的延遲。響應超時閾值設置為 1 秒。
Log Analysis
集中式日志在分析分布式系統中存在的問題時十分有效。Elasticsearch, Logstash, 和 Kibana 的技術棧讓你輕松搜索和分析你的日志,系統利用率和網絡活動數據。在這篇文章中可以找到相關的描述。
Security
高級安全配置超出了這個概念驗證項目的范圍。要更真實地模擬真實系統,請考慮使用 https 和 JCE 密鑰庫來加密微服務密碼和配置服務器屬性內容(請參閱文檔以了解詳細信息)。
Infrastructure Automation(基礎設置自動化)
部署相互依賴的微服務,比部署整體應用程序要復雜得多。擁有完全自動化的基礎設施非常重要。采用持續交付方式,我們可以獲得以下好處:
·隨時發布軟件的能力。
·任何構建可能最終成為一個 release。
·一次構建工件,根據需要進行部署
這是在這個項目中實現一個簡單的持續交付工作流程:
在這個配置中,Travis CI 為每個成功的 Git 推送建立標記的圖像。因此,Docker Hub 上的每個微服務總是有最新的鏡像,而舊鏡像使用 Git commit hash 進行標記。如果需要的話,部署它們很容易并且快速回滾。
How to Run All the Things?
你將啟動 8 個 Spring Boot 應用程序,4 個 MongoDB 實例和 RabbitMq。確保您的機器上有 4 Gb RAM。通過 Gateway,Registry,Config,Auth Service 和 Account Service,您始終可以運行重要的服務。
開始之前
·安裝 Docker 和 Docker Compose。
·導出環境變量: CONFIG_SERVICE_PASSWORD, NOTIFICATION_SERVICE_PASSWORD, STATISTICS_SERVICE_PASSWORD, ACCOUNT_SERVICE_PASSWORD, MONGODB_PASSWORD
Production Mode
在這種模式下,會從 docker hub 下抓取最新的 images,只需復制 docker-compose.yml 并點擊 docker-compose up -d
Development Mode
如果您想自己構建鏡像(例如,在代碼中進行了一些更改),則必須克隆所有 repository 并使用 Maven 構建。然后運行
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
docker-compose.dev.yml 繼承了 docker-compose.yml,可以在本地構建鏡像并公開所有容器端口以方便開發。
·Important Endpoints
·Ilocalhost:80 – Gateway
·Ilocalhost:8761 – Eureka Dashboard
·Ilocalhost:9000 – Hystrix Dashboard
·Ilocalhost:8989 – Turbine stream (source for Hystrix Dashboard)
·Ilocalhost:15672 – RabbitMq management
注意
所有 Spring Boot 應用程序都需要依賴運行中的 Config Server 才能啟動。但是,我們可以同時啟動所有的容器,因為 docker-compose 選項始終存在 Spring Boot 的 fail-fast 和 restart 屬性。這意味著所有從屬容器將嘗試重新啟動,直到配置服務器啟動并運行。
此外,在所有應用程序啟動之后,服務發現機制還需要一些時間,服務都不會立馬被客戶端的發現,直到實例,Eureka 服務器和客戶端在其本地緩存中都具有相同的元數據,因此可能需要 3 個心跳。默認心跳周期是 30 秒。
關于如何理解 Spring Cloud 和 Docker 的微服務架構問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。