使用Spring Cloud和Docker構建微服務架構

来源:http://www.cnblogs.com/oopsguy/archive/2017/08/06/7292474.html
-Advertisement-
Play Games

如何使用Spring Boot、Spring Cloud、Docker和Netflix的一些開源工具來構建一個微服務架構。本文通過使用Spring Boot、Spring Cloud和Docker構建的概念型應用示例,提供了瞭解常見的微服務架構模式的起點。 ...


原文:https://dzone.com/articles/microservice-architecture-with-spring-cloud-and-do
作者:Alexander Lukyanchikov
譯者:Oopsguy

如何使用Spring Boot、Spring Cloud、Docker和Netflix的一些開源工具來構建一個微服務架構。

本文通過使用Spring Boot、Spring Cloud和Docker構建的概念型應用示例,提供了瞭解常見的微服務架構模式的起點。

該代碼可以在Github上獲得,並且在Docker Hub上提供了鏡像。您只需要一個命令即可啟動整個系統。

我選擇了一個老項目作為這個系統的基礎,它的後端以前是單一應用。此應用提供了處理個人財務、整理收入開銷、管理儲蓄、分析統計和創建簡單預測等功能。

功能服務

整個應用分解為三個核心微服務。它們都是可以獨立部署的應用,圍繞著某些業務功能進行組織。

使用Spring Cloud和Docker構建微服務架構

賬戶服務

包含一般用戶輸入邏輯和驗證:收入/開銷記錄、儲蓄和賬戶設置。

方法 路徑 描述 用戶驗證 UI可用
GET /accounts/{account} 獲取指定賬戶數據
GET /accounts/current 獲取當前賬戶數據 x x
GET /accounts/demo 獲取演示賬戶數據(預先填入收入/開銷記錄等) x
PUT /accounts/current 保存當前賬戶數據 x x
POST /accounts/ 註冊新賬戶 x

統計服務

計算主要的統計參數,並捕獲每一個賬戶的時間序列。數據點包含基於貨幣和時間段正常化後的值。該數據可用於跟蹤賬戶生命周期中的現金流量動態。

方法 路徑 描述 用戶驗證 UI可用
GET /statistics/{account} 獲取指定賬戶統計數據
GET /statistics/current 獲取當前賬戶的統計數據 x x
GET /statistics/demo 獲取演示賬戶統計數據 x
PUT /statistics/{account} 創建或更新指定賬戶的時間序列數據點。

通知服務

存儲用戶的聯繫信息和通知設置(如提醒和備份頻率)。安排工作人員從其它服務收集所需的信息並向訂閱的客戶發送電子郵件。

方法 路徑 描述 用戶驗證 UI可用
GET /notifications/settings/current 獲取當前賬戶的通知i設置 x x
PUT /notifications/settings/current 保存當前賬戶的通知設置 x x

註意

  • 每一個微服務擁有自己的資料庫,因此沒有辦法繞過API直接訪問持久數據。
  • 在這個項目中,我使用MongoDB作為每一個服務的主資料庫。擁有一個多種類持久化架構(polyglot persistence architecture)也是很有意義的。
  • 服務間(Service-to-service)通信是非常簡單的:微服務僅使用同步的REST API進行通信。現實中的系統的常見做法是使用互動風格的組合。例如,執行同步的GET請求檢索數據,並通過消息代理(broker)使用非同步方法執行創建/更新操作,以便解除服務和緩衝消息之間的耦合。然而,這帶給我們是最終的一致性

基礎設施服務

分散式系統中常見的模式,可以幫助我們描述核心服務是怎樣工作的。Spring Cloud提供了強大的工具,可以增強Spring Boot應用的行為來實現這些模式。我會簡要介紹一下:

基礎設施服務

配置服務

Spring Cloud Config是分散式系統的水平擴展集中式配置服務。它使用了當前支持的本地存儲、Git和Subversion等可拔插存儲庫層(repository layer)。

在此項目中,我使用了native profile,它簡單地從本地classpath下載入配置文件。您可以在配置服務資源中查看shared目錄。現在,當通知服務請求它的配置時,配置服務將響應回shared/notification-service.ymlshared/application.yml(所有客戶端應用之間共用)。

客戶端使用

只需要使用sprng-cloud-starter-config依賴構建Spring Boot應用,自動配置將會完成其它工作。

現在您的應用中不需要任何嵌入的properties,只需要提供有應用名稱和配置服務url的bootstrap.yml即可:

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

使用Spring Cloud Config,您可以動態更改應用配置

比如,EmailService bean使用了@RefreshScope註解。這意味著您可以更改電子郵件的內容和主題,而無需重新構建和重啟通知服務應用。

首先,在配置伺服器中更改必要的屬性。然後,對通知服務執行刷新請求:curl -H "Authorization: Bearer #token#" -XPOST http://127.0.0.1:8000/notifications/refresh

您也可以使用webhook來自動執行此過程

註意

  • 動態刷新存在一些限制。@RefreshScope不能和@Configuraion類一同工作,並且不會作用於@Scheduled方法。
  • fail-fast屬性意味著如果Spring Boot應用無法連接到配置服務,將會立即啟動失敗。當您一起啟動所有應用時,這非常有用。
  • 下麵有重要的安全提示

授權服務

負責授權的部分被完全提取到單獨的伺服器,它為後端資源服務提供OAuth2令牌。授權伺服器用於用戶授權以及在周邊內進行安全的機器間通信。

在此項目中,我使用密碼憑據作為用戶授權的授權類型(因為它僅由本地應用UI使用)和客戶端憑據作為微服務授權的授權類型。

Spring Cloud Security提供了方便的註解和自動配置,使其在伺服器端或者客戶端都可以很容易地實現。您可以在文檔中瞭解到更多信息,併在授權伺服器代碼中檢查配置明細。

從客戶端來看,一切都與傳統的基於會話的授權完全相同。您可以從請求中檢索Principal對象、檢查用戶角色和其它基於表達式訪問控制和@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。在現實系統中,這個數量可以非常快速地增長,同時整個系統將變得非常複雜。實際上,一個複雜頁面的渲染可能涉及到數百個服務。

理論上,客戶端可以直接向每個微服務直接發送請求。但是這種方式是存在挑戰和限制的,如果需要知道所有端點的地址,分別對每一段信息執行http請求,將結果合併到客戶端。另一個問題是,這不是web友好協議,可能只在後端使用。

通常一個更好的方法是使用API網關。它是系統的單個入口點,用於通過將請求路由到適當的後端服務或者通過調用多個後端服務並聚合結果來處理請求。此外,它還可以用於認證、insights、壓力測試、金絲雀測試(canary testing)、服務遷移、靜態響應處理和主動變換管理。

Netflix開源這樣的邊緣服務,現在用Spring Cloud,我們可以用一個@EnabledZuulProxy註解來啟用它。在這個項目中,我使用Zuul存儲靜態內容(UI應用),並將請求路由到適當的微服務。以下是一個簡單的基於首碼(prefix-based)路由的通知服務配置:

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

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

服務發現

另一種常見的架構模式是服務發現。它允許自動檢測服務實例的網路位置,由於自動擴展、故障和升級,它可能會動態分配地址。

服務發現的關鍵部分是註冊。我使用Netflix Eureka進行這個項目,當客戶端需要負責確定可以用的服務實例(使用註冊伺服器)的位置和跨平臺的負載均衡請求時,Eureka就是客戶端發現模式的一個很好的例子。

使用Spring Boot,您可以使用spring-cloud-starter-eureka-server依賴、@EnabledEurekaServer註解和簡單的配置屬性輕鬆構建Eureka註冊中心(Eureka Registry)。

使用@EnabledDiscoveryClient註解和帶有應用名稱的bootstrap.yml來啟用客戶端支持:

spring:
  application:
    name: notification-service

現在,在應用啟動時,它將向Eureka伺服器註冊並提供元數據,如主機和埠、健康指示器URL、主頁等。Eureka接收來自從屬於某服務的每個實例的心跳消息。如果心跳失敗超過配置的時間表,該實例將從註冊表中刪除。

此外,Eureka還提供了一個簡單的界面,您可以通過它來跟蹤運行中的服務和可用實例的數量:http://localhost:8761

Eureka儀錶盤

負載均衡器、斷路器和Http客戶端

Netflix OSS提供了另一套很棒的工具。

Ribbon

Ribbon是一個客戶端負載均衡器,可以很好地控制HTTP和TCP客戶端的行為。與傳統的負載均衡器相比,每次線上調用都不需要額外的跳躍——您可以直接聯繫所需的服務。

它與Spring Cloud和服務發現是集成在一起的,可開箱即用。Eureka客戶端提供了可用伺服器的動態列表,因此Ribbon可以在它們之間進行平衡。

Hystrix

Hystrix是斷路器模式的一種實現,它可以通過網路訪問依賴來控制延遲和故障。中心思想是在具有大量微服務的分散式環境中停止級聯故障。這有助於快速失敗並儘快恢復——自我修複在容錯系統中是非常重要的。

除了斷路器控制,在使用Hystrix,您可以添加一個備用方法,在主命令失敗的情況下,該方法將被調用以獲取預設值。

此外,Hystrix生成每個命令的執行結果和延遲的度量,我們可以用它來監視系統的行為

Feign

Feign是一個聲明式HTTP客戶端,能與Ribbon和Hystrix無縫集成。實際上,通過一個spring-cloud-starter-feign依賴和@EnabledFeignClients註解,您可以使用一整套負載均衡器、斷路器和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——statistics-service,這得益於Eureka的自動發現(但顯然您可以使用特定的URL訪問任何資源)。

監控儀錶盤

在這個項目配置中,Hystrix的每一個微服務都通過Spring Cloud Bus(通過AMQP broker)將指標推送到Turbine。監控項目只是一個使用了TurbineHystrix儀錶盤的小型Spring Boot應用。

讓我們看看系統行為在負載下:賬戶服務調用統計服務和它在一個變化的模擬延遲下的響應。響應超時閾值設置為1秒。

監控儀錶盤

日誌分析

集中式日誌記錄在嘗試查找分散式環境中的問題時非常有用。Elasticsearch、Logstash和Kibana技術棧可讓您輕鬆搜索和分析您的日誌、利用率和網路活動數據。在我的另一個項目中已經有現成的Docker配置。

安全

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

基礎設施自動化

部署微服務比部署單一的應用的流程要複雜得多,因為它們相互依賴。擁有完全基礎設置自動化是非常重要的。我們可以通過持續交付的方式獲得以下好處:

  • 隨時發佈軟體的能力。
  • 任何構建都可能最終成為一個發行版本。
  • 構建工件(artifact)一次,根據需要進行部署。

這是一個簡單的持續交付工作流程,在這個項目的實現:

在此配置中,Travis CI為每一個成功的Git推送創建了標記鏡像。因此,每一個微服務在Docker Hub上的都會有一個latest鏡像,而較舊的鏡像則使用Git提交的哈希進行標記。如果有需要,可以輕鬆部署任何一個,並快速回滾。

基礎設施自動化

如何運行全部?

這真的很簡單,我建議您嘗試一下。請記住,您將要啟動8個Spring Boot應用、4個MongoDB實例和RabbitMq。確保您的機器上有4GB的記憶體。您可以隨時通過網關、註冊中心、配置、認證服務和賬戶中心運行重要的服務。

運行之前

  • 安裝Docker和Docker Compose。
  • 配置環境變數:CONFIG_SERVICE_PASSWORD, NOTIFICATION_SERVICE_PASSWORD, STATISTICS_SERVICE_PASSWORD, ACCOUNT_SERVICE_PASSWORD, MONGODB_PASSWORD

生產模式

在這種模式下,所有最新的鏡像都將從Docker Hub上拉取。只需要複製docker-compose.yml並執行docker-compose up -d即可。

開發模式

如果您想自己構建鏡像(例如,在代碼中進行一些修改),您需要克隆所有倉庫(repository)並使用Mavne構建工件(artifact)。然後,運行docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

docker-compose.dev.yml繼承了docker-compose.yml,附帶額外配置,可在本地構建鏡像,並暴露所有容器埠以方便開發。

重要的端點(Endpoint)

  • localhost:80 —— 網關
  • localhost:8761 —— Eureka儀錶盤
  • localhost:9000 —— Hystrix儀錶盤
  • localhost:8989 —— Turbine stream(Hystrix儀錶盤來源)
  • localhost:15672 —— RabbitMq管理

註意

所有Spring Boot應用都需要運行配置伺服器才能啟動。得益於Spring Boot的fail-fast屬性和docker-compsoe的restart:always選項,我們可以同時啟動所有容器。這意味著所有依賴的容器將嘗試重新啟動,直到配置伺服器啟動運行為止。

此外,服務發現機制在所有應用啟動後需要一段時間。在實例、Eureka伺服器和客戶端在其本地緩存中都具有相同的元數據之前,任何服務都不可用於客戶端發現,因此可能需要3次心跳。預設的心跳周期為30秒。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本節作業: 熟練使用類和模塊,寫一個交互性強、有衝突的程式。 一、作業目的 1、規範程式寫法,要按照模塊來規範書寫; 2、類的使用,文件之間的調用練習; 3、思路的開闊,自己編寫衝突,實現調用; 4、對基礎知識的熟練掌握。 本文寫了一個決鬥系統,兩個男的為了一個女的進行決鬥,獲勝者贏得美女放心,失敗 ...
  • 本文介紹將各種Spring的配置方式,幫助您瞭解配置Spring應用的複雜性。Spring是一個非常受歡迎的Java框架,它用於構建web和企業應用。不像許多其他框架只關註一個領域,Spring框架提供了各種功能,通過項目組合來滿足當代業務需求。Spring框架提供了多種靈活的方式配置Bean。例如... ...
  • mybatis 詳解(四)------properties以及別名定義 ...
  • 目錄 · 總述 · 記憶 · 效果 · 面向對象設計原則 · 創建型模式 · 單例模式(Singleton) · 效果 · 分類 · 代碼(餓漢式) · 代碼(懶漢式) · 代碼(雙重檢測鎖式) · 代碼(靜態內部類式) · 代碼(枚舉單例) · 代碼(使用反射的破解與防禦) · 代碼(使用序列化的 ...
  • 定義(百度百科): 責任鏈模式是一種設計模式。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。 ...
  • 最近看完了 backbone.js 的源碼,這裡對於源碼的細節就不再贅述了,大家可以 star 我的源碼閱讀項目(https://github.com/JiayiLi/source-code-study)進行參考交流,有詳細的源碼註釋,以及知識總結,同時 google 一下 backbone 源碼, ...
  • A代碼編輯器,線上模版編輯,仿開發工具編輯器,pdf線上預覽,文件轉換編碼B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本,處理類,service等完整模塊C 集成阿 ...
  • 寫在前面 最近在讀一本來自淘寶技術團隊大牛的書,名字叫《大型網站系統與Java中間件實踐》。開篇的章節詳細地介紹了一個網站架構由小變大不斷演進的過程,其中從單機架構升級到集群架構的過程中著重介紹了關於session同步問題, 這也是很多人在聊到分散式時繞不過去的話題。下麵就整理下書中的內容,也算是做 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...