Spring Cloud在Netflix後時代的走向?
如果有人問你關於Spring Cloud的問題,那麼你首先想到的可能是Netflix OSS的支援。對Eureka,Zuul或Ribbon等工具的支援不僅由Spring提供,還可基於其他流行框架Apache Camel,Vert.x或Micronaut等構建微服務架構。
目前,Spring Cloud Netflix是最受歡迎的專案,它是Spring Cloud的一部分。它在GitHub上有大約3.2k的星星,而第二個同類最好的大約有1.4k。
但是,Pivotal宣佈大部分Spring Cloud Netflix模組正在進入維護模式,這是非常令人驚訝的。您可以在Spencer Gibb在Spring部落格上釋出的帖子中閱讀更多相關內容。
讓我們簡要介紹一下這些變化。
從Spring Cloud Greenwich釋出列車開始,Netflix OSS,Archaius,Hystrix,Ribbon和Zuul正在進入維護模式。這意味著不會向這些模組新增任何新功能,Spring Cloud團隊只會執行一些錯誤修復並修復安全問題。維護模式不包括仍受支援的Eureka模組。
對這些變化的解釋非常簡單。主要是其中兩個原因:
目前,Netflix並未積極開發Ribbon和Hystrix,儘管它們仍在大規模部署。
此外,Hystrix已經被稱為Atlas的遙測新解決方案所取代。
Zuul的情況並不那麼明顯,Netflix於2018年5月宣佈Zuul 2的開源。新版Zuul閘道器建立在Netty伺服器之上,包括一些改進和新功能。您可以在Netflix部落格上閱讀有關它們的更多資訊。
儘管Netflix雲團隊做出了這一決定,但Spring Cloud團隊已經放棄了Zuul模組的開發。我只能猜測這是因為早先決定在Spring Cloud系列中啟動了一個專門用於API閘道器的Spring Cloud Gateway新模組。
最後一塊拼圖是Eureka:這是一個發現伺服器。它仍在開發中,但這裡的情況也很有趣。我將在本文的下一部分中對此進行描述。
所有這些訊息激勵我看一下Spring Cloud的現狀,並討論未來可能發生的一些變化。作為Mastering Spring Cloud的一本書的作者,我試圖跟隨該專案的發展以保持最新狀態。值得一提的是,我們的組織內部還有微服務 - 當然是使用Eureka,Zuul和Ribbon等模組構建在Spring Boot和Spring Cloud之上。在本文中,我想討論一些流行的微服務模式,如服務發現,分散式配置,客戶端負載平衡和API閘道器。
服務發現
Eureka是唯一尚未轉移到維護模式的重要Spring Cloud Netflix模組。但是,我不會說它是積極開發的。Netflix維護的儲存庫中的最後一次提交是從1月11日開始的。前段時間,他們已經開始研究Eureka 2,但似乎這項工作已被放棄,或者他們只是推遲了最新版本的開源。
在這裡您可以找到一個有趣的評論:“2.x分支目前被凍結,因為我們已經對eureka2進行了一些內部更改,並且沒有任何時間來開源新的變更。”所以,我們有兩種可能性。也許,Netflix將決定將這些內部更改作為Eureka伺服器的第2版開源。值得記住的是,Eureka是Netflix直接大規模使用的經過實戰驗證的解決方案,也可能是許多其他組織透過Spring Cloud實現驗證過的。
第二個選項是選擇另一個發現伺服器。目前,Spring Cloud支援基於各種工具的發現:ZooKeeper,Consul,Alibaba Nacos和Kubernetes。事實上,Kubernetes基於etcd。Spring Cloud也正在開發對etcd的支援,但它還處於孵化階段,目前還不知道它是否會被推廣到官方釋出列車。在我看來,這些解決方案中有一個領導者--HashiCorp的Consul。
Consul現在被描述為服務網格解決方案,提供具有服務發現,配置和分段功能的全功能控制平面。它可以用作基於微服務的體系結構中的發現伺服器或鍵/值儲存。與Consul的整合由Spring Cloud Consul專案實現。要為您的應用程式啟用Consul客戶端,您只需要在Maven中包含以下依賴項pom.xml:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> |
預設情況下,Spring嘗試在地址localhost:8500上與Consul連線。如果您需要覆蓋此地址,則應在其中設定適當的屬性application.yml:
spring: cloud: consul: host: 192.168.99.100 port: 8500 |
您可以使用作為Docker容器啟動的Consul的本地例項輕鬆測試此解決方案:
$ docker run -d --name consul -p 8500:8500 consul |
正如您所看到的,使用Spring Cloud進行Consul發現實現非常簡單 - 就像Eureka一樣。Consul對Eureka有一個無可置疑的優勢 - 它由HashiCorp持續維護和開發。它的受歡迎程度快速增長。它是HashiCorp最大的生態系統的一部分,包括Vault,Nomad和Terraform。與Eureka相比,Consul不僅可以用於服務發現,還可以用作基於微服務的體系結構中的配置伺服器。
分散式配置
Netflix Archaius是一個有趣的解決方案,用於管理微服務架構中的外部化配置。雖然它提供了一些有趣的功能,如動態和型別屬性,或者支援動態資料來源,如URL,JDBC或AWS DynamoDB,但Spring Cloud也決定將其轉移到維護模式。然而,由於Pivotal團隊和社群 - Spring Cloud Config完全建立的類似專案的存在,Spring Cloud Archaius的受歡迎程度有限。
Spring Cloud Config支援多個源儲存庫,包括Git,JDBC,Vault或簡單檔案。您可以在我之前的帖子中找到許多使用此專案為您的微服務提供分散式配置的示例。今天,我不打算談論它。
正如我在上一節末尾提到的,Consul也可以用作配置伺服器。如果您使用Eureka作為發現伺服器,使用Spring Cloud Config作為配置伺服器是很自然的選擇,因為Eureka根本不提供此類功能。如果您決定使用Consul,情況就不是這樣。現在選擇兩種解決方案是有意義的:Spring Cloud Consul Config和Spring Cloud Config。
當然,它們都有其優點和缺點。例如,您可以使用Consul節點輕鬆構建叢集,而使用Spring Cloud Config則必須依賴外部發現。
現在,讓我們看看如何使用Spring Cloud Consul來管理應用程式中的外部配置。要在應用程式端啟用它,您只需要在Maven中包含以下依賴項pom.xml:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> </dependency> |
與服務發現相同,如果要覆蓋某些預設客戶端設定,則需要設定屬性spring.cloud.consul.*。但是,必須在bootstrap.yml內部提供這樣的配置。
spring: application: name: callme-service cloud: consul: host: 192.168.99.100 port: 8500 |
在Consul上建立的屬性源的名稱應該bootstrap.yml與config資料夾中提供的應用程式名稱相同。您應該建立server.port值為的值 0,以強制Spring Boot隨機生成偵聽埠號。如果需要設定應用程式的預設偵聽埠,則應使用以下配置: key 是config/callme-service/server.port 值是0。
API閘道器
Spring Cloud Netflix Zuul的繼任者是Spring Cloud Gateway。這個專案大約在兩年前開始,現在是第二個最受歡迎的Spring Cloud專案,在GitHub上有1.4k星。它提供了一個建立在Spring Ecosystem之上的API閘道器,包括:Spring 5,Spring Boot 2和Project Reactor。它在Netty上執行,不能與Tomcat或Jetty等傳統的servlet容器一起使用。它允許我們定義路由,謂詞和過濾器。
API閘道器就像每個Spring Cloud微服務一樣,可以輕鬆地與基於Consul的服務發現整合。我們只需要在裡面包含適當的依賴項pom.xml。我們將使用Spring Cloud庫的最新開發版本 - 2.2.0.BUILD-SNAPSHOT。這是所需依賴項的列表:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> <version>2.2.0.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> <version>2.2.0.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.0.BUILD-SNAPSHOT</version> </dependency> |
Consul還將提供閘道器配置。因為我們有比樣本微服務更多的配置設定,我們將它儲存為YAML檔案。為此,我們應該在Consul的Key / Value的/config/gateway-service/data路徑下建立一個YAML檔案 。下面顯示的配置啟用服務發現整合並定義到下游服務的路由。每條路由都包含在服務發現中註冊的目標服務的名稱,用於下游服務公開的呼叫端點的匹配路徑和重寫路徑。我們的API閘道器在啟動時載入以下配置:
spring: cloud: gateway: discovery: locator: enabled: true routes: - id: caller-service uri: lb://caller-service predicates: - Path=/caller/** filters: - RewritePath=/caller/(?.*), /$\{path} - id: callme-service uri: lb://callme-service predicates: - Path=/callme/** filters: - RewritePath=/callme/(?.*), /$\{path} |
最後一步是強制gateway-service讀取儲存為YAML的配置。為此,我們需要將屬性設定spring.cloud.consul.config.format為YAML。這是bootstrap.yml裡面提供的完整配置。
spring: application: name: gateway-service cloud: consul: host: 192.168.99.100 config: format: YAML |
客戶端負載均衡器
在2.2.0.BUILD-SNAPSHOTSpring Cloud Commons Ribbon 版本中,它仍然是HTTP客戶端的主要自動配置負載均衡器。儘管Spring Cloud團隊已宣佈Spring Cloud Load Balancer將成為Ribbon的繼任者,但我們目前在文件或網路上找不到有關該專案的更多資訊。我們可能期望Netflix Ribbon也是如此,即任何配置對我們來說都是透明的,特別是如果我們使用發現客戶端。目前,該spring-cloud-loadbalancer模組是Spring Cloud Commons專案的一部分。您可以透過宣告以下依賴項將其直接包含在您的應用程式中pom.xml:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> <version>2.2.0.BUILD-SNAPSHOT</version> </dependency> |
出於測試目的,排除一起包含spring-cloud-starter-consul-discovery 啟動器的一些Netflix模組是值得的 。現在,我們確信Ribbon不用作了後臺用作負載均衡器。這是我為示例應用程式設定的排除列表:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> <version>2.2.0.BUILD-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-archaius</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-core</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-httpclient</artifactId> </exclusion> <exclusion> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon-loadbalancer</artifactId> </exclusion> </exclusions> </dependency> |
首先,我們應該用我們的main或配置類註釋@LoadBalancerClient。與往常一樣,客戶端的名稱應與登錄檔中註冊的目標服務的名稱相同。註釋還應包含具有客戶端配置的類。
@SpringBootApplication @LoadBalancerClients({ @LoadBalancerClient(name = "callme-service", configuration = ClientConfiguration.class) }) public class CallerApplication { public static void main(String[] args) { SpringApplication.run(CallerApplication.class, args); } @Bean RestTemplate template() { return new RestTemplate(); } } |
這是我們的負載均衡器配置類。它包含單個宣告@Bean。我選擇了RoundRobinLoadBalancer型別。
public class ClientConfiguration { @Bean public RoundRobinLoadBalancer roundRobinContextLoadBalancer(LoadBalancerClientFactory clientFactory, Environment env) { String serviceId = clientFactory.getName(env); return new RoundRobinLoadBalancer(serviceId, clientFactory .getLazyProvider(serviceId, ServiceInstanceSupplier.class), -1); } } |
最後,這是caller-service控制器的實現。它LoadBalancerClientFactory直接用於查詢callme-service可用例項的列表。然後,它選擇單個例項,獲取其主機和埠,並將其設定為目標URL。
@RestController @RequestMapping("/caller") public class CallerController { @Autowired Environment environment; @Autowired RestTemplate template; @Autowired LoadBalancerClientFactory clientFactory; @GetMapping public String call() { RoundRobinLoadBalancer lb = clientFactory.getInstance("callme-service", RoundRobinLoadBalancer.class); ServiceInstance instance = lb.choose().block().getServer(); String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/callme"; String callmeResponse = template.getForObject(url, String.class); return "I'm Caller running on port " + environment.getProperty("local.server.port") + " calling-> " + callmeResponse; } |
總結
下圖說明了樣本系統的架構:
我們有兩個例項callme-service,一個例項caller-service,它使用Spring Cloud Balancer查詢可用例項列表callme-service。埠是動態生成的。API閘道器從外部客戶端隱藏了我們系統的複雜性。它在埠8080上可用,並根據請求上下文路徑將請求轉發到下游。
啟動後,您應該在Consul節點上註冊所有微服務。
現在,您可以嘗試caller-service透過閘道器公開的端點:http:// localhost:8080 / caller。
示例應用程式原始碼可在儲存庫中的GitHub上獲得。
相關文章
- Spring Cloud 關於:Spring Cloud Netflix HystrixSpringCloud
- Spring Cloud Netflix—使用EurekaClientSpringCloudclient
- Spring Cloud Netflix—示例在Ribbon中禁用Eureka使用SpringCloud
- Spring Boot整合Spring Cloud Netflix元件Spring BootCloud元件
- Spring Cloud Netflix—如何加入HystrixSpringCloud
- 微服務2.0時代:Spring Cloud Netflix與 Kubernetes&Istio比較微服務SpringCloud
- spring cloud微服務分散式雲架構-Spring Cloud NetflixSpringCloud微服務分散式架構
- 我是如何替換Spring Cloud Netflix的?SpringCloud
- Spring Cloud正式移除Hystrix、Zuul等Netflix OSS元件SpringCloudZuul元件
- Spring Cloud Netflix—自定義Ribbon客戶端SpringCloud客戶端
- Spring Cloud Netflix—斷路器:Hystrix客戶端SpringCloud客戶端
- Spring Cloud Netflix 概覽和架構設計SpringCloud架構
- Spring Cloud Netflix—宣告性REST客戶端:FeignSpringCloudREST客戶端
- Spring Cloud Netflix—服務發現:Eureka伺服器SpringCloud伺服器
- 人類正從IT時代改革走向DT時代!
- Spring Cloud Netflix的3大元件應用 Eureka&Ribbon&HystrixSpringCloud元件
- Spring Cloud 2021.0.1 移除了Hystrix、Zuul等Netflix元件SpringCloudZuul元件
- Spring Cloud Netflix—客戶端負載平衡器:RibbonSpringCloud客戶端負載
- 基於Spring Cloud和Netflix OSS構建微服務,Part 2SpringCloud微服務
- 基於Spring Cloud和Netflix OSS 構建微服務-Part 1SpringCloud微服務
- 基於Spring Cloud Netflix的TCC柔性事務和EDA事件驅動示例SpringCloud事件
- 後“帝國”時代:微軟在《帝國時代2》之後的RTS嘗試微軟
- Spring Cloud 2020.0.0正式釋出,再見了NetflixSpringCloud
- 程式猿在後IT時代的交流進化
- 後深度學習時代,計算機視覺技術如何走向未來?深度學習計算機視覺
- Spring Cloud Config-Git後端SpringCloudGit後端
- 升級Spring Cloud到Finchley後的一點坑SpringCloud
- 日媒:世界盃也走向“比拼”大資料的時代大資料
- 在大語言模型時代,AI Chatbots下一步將走向何方?模型AI
- Spring Cloud(二):Spring Cloud ConfigSpringCloud
- Spring cloudSpringCloud
- Spring Cloud的核心特性SpringCloud
- 詳細剖析Spring Cloud 和Spring Cloud Alibaba的前世今生SpringCloud
- Spring Cloud雲架構-Config Git後端SpringCloud架構Git後端
- dubbogo 3.0:牽手 gRPC 走向雲原生時代GoRPC
- 雲技術將開啟Netflix般的雲遊戲時代遊戲
- 大咖論道資料透明度(Transparency):後疫情時代如何走向資料驅動?
- spring cloud 和 阿里微服務spring cloud AlibabaSpringCloud阿里微服務