[SpringCloud-Eureka] 使用spring.factories機制來實現註冊中心相容Eureka和Zookeeper
使用SpringBoot開發微服務時,需要通過註冊中心來實現服務之間的發現機制,Eureka和Zookeeper都是常用的
註冊中心框架,我們可以選擇其中之一,現在面臨一個特殊的需求,我們同時存在Eureka和ZK,但是有時候會使用
Eureka,有時候使用ZK,怎麼辦?首先一點需要明確的是,不管使用哪一個,肯定只能選擇其一,不存在說同時使
用2個,但情況是我兩者都有可能使用,怎麼辦?比如環境A使用Eureka,另有一套環境B使用ZK,如何在程式碼侵入盡
量低的情況下去適配註冊中心的服務發現框架,涉及改動越小越好;
- 1.首先我們簡單分析一下大概的情況
不管使用哪一個註冊中心,我麼你都通過在啟動類添加註解@@EnableDiscoveryClient來實現的,這個註解是在
spring-cloud-commons包裡面的,這個註解和具體的註冊中心實現細節解耦的,不管使用Eureka還是ZK都是這個註解;- 2.我們先嚐試引入Eureka和ZK的註冊依賴座標,這裡就不具體指定版本了,版本會和springcloud版本適配:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency>
- 然後啟動工程,會發現報下面的錯:
Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration$
ServiceRegistryEndpointConfiguration required a single bean, but 2 were found:
- eurekaRegistration: defined by method ‘eurekaRegistration’ in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.class] - zookeeperServiceDiscovery: defined by method ‘zookeeperServiceDiscovery’ in class path resource [org/springframework
/cloud/zookeeper/serviceregistry/ZookeeperAutoServiceRegistrationAutoConfiguration.class]
注意這裡如果工程沒有依賴spring-boot-starter-actuator元件的話,是不會報錯的,具體原因未深究,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 提示上面的錯,看的很明白,說有一個單例bean但是找到了兩個例項,全域性搜尋這兩個類,發現這兩個類的位置如下:
EurekaClientAutoConfiguration:類位於spring-cloud-netflix-eureka-cleint包下,這個包是通過spring-cloud-starter-eureka
傳遞依賴進來的
ZookeeperAutoServiceRegistrationAutoConfiguration:類位於spring-cloud-zookeeper-discovery包下,這個是spring-cloud-starter-zookeeper-discovery傳遞依賴進來的,
- 3.找到了這兩個衝突的bean所在的jar包之後,我們找到spring-cloud-netflix-eureka-cleint jar包的resources/META-INF/spring.factories檔案,發現如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\
org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration
org.springframework.cloud.client.discovery.EnableDiscoveryClient=\
org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration
- 同理我們找spring-cloud-zookeeper-discoveryjar包的resources/META-INF/spring.factories檔案,發現如下:
# Auto Configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.zookeeper.discovery.RibbonZookeeperAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.dependency.DependencyFeignClientAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.dependency.DependencyRibbonAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.dependency.DependencyRestTemplateAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.dependency.ZookeeperDependenciesAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherAutoConfiguration,\
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperAutoServiceRegistrationAutoConfiguration,\
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperServiceRegistryAutoConfiguration,\
org.springframework.cloud.zookeeper.support.CuratorServiceDiscoveryAutoConfiguration
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.zookeeper.discovery.dependency.DependencyEnvironmentPostProcessor
org.springframework.cloud.client.discovery.EnableDiscoveryClient=\
org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClientConfiguration
- 4.到此我們大概捋一捋思路:註冊中心只能選擇某一個,我們同時引入了ZK和Eureka的註冊客戶端jar包,執行提示我們一個單例的bean找到了倆,我們找到了倆類,發現確實在我們引入的jar包裡面,然後在jar包裡面,我們發現了spring.factories檔案裡面就寫著這兩個類的名字,我們仔細看看這個檔案,發現裡面寫的是一些鍵值對,鍵key就是org.springframework.boot.autoconfigure.EnableAutoConfiguration,值是一系列的配置類,到這裡,我們簡單瞭解下spring.factories的原理,工程掃描META-INF下面的spring.factories檔案來決定需要載入哪些配置類,這給我們解決該問題提供了一個思路:
我們把spring-cloud-netflix-eureka-cleint包下面的spring.factories檔案裡面
的org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\去掉,
把spring-cloud-zookeeper-discovery包裡面的org.springframework.cloud.zookeeper.serviceregistry.ZookeeperAutoServiceRegistrationAutoConfiguration,\去掉,
理論上,再次啟動時就不會保證錯誤了,驗證確實如此,因為不會自動配置這兩個類了,但是,
這兩行內容寫在自己的工程的spring.factories裡面,然後不就可以做一個簡易的開關了嗎?
- 5.解決:
在自己的工程下新建resources/META-INF/spring.factories檔案,檔案內容如下:
#org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
#org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperAutoServiceRegistrationAutoConfiguration,\
org.springframework.cloud.zookeeper.discovery.RibbonZookeeperAutoConfiguration,\
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperServiceRegistryAutoConfiguration
說明:
這裡有五行程式碼,前面兩行說明設定自動配置的是eureka的註冊發現,後面四行是ZK的註冊發現,ZK配置了三個類,為什
麼是三個後面簡單解釋,是因為我在測試的時候,只有一個的話會有問題;此時,我們工程引入的原始spring-cloud-netflix-eureka-cleint和spring-cloud-zookeeper-discovery包的spring.factories裡面的配置被我們去掉了,挪到了我們自
己的工程下面,然後我們現在按照上面的配置啟動,就發現可以註冊到ZK了,且不會報bena的衝突錯誤了,然後我們註釋掉後四行,
放開前兩行,就可以註冊到Eureka了,
- 6.問題
為什麼第五點裡面,ZK有三項配置挪出來了,因為僅僅把ZookeeperServiceRegistryAutoConfiguration挪出來的話,再註冊到ZK的時候回報一個zk相關的bean找不到,後來把ZookeeperAutoServiceRegistrationAutoConfiguration挪出來之後就沒問題了,我猜想是把ZookeeperServiceRegistryAutoConfiguration挪出來後,他的配置時機提前了,導致一些依賴的bean沒有在它之前初始化,至於RibbonZookeeperAutoConfiguration為什麼要挪出來,這個是ribbon服務呼叫相關的,不挪出來之前,測試註冊到Eureka是ok的,但是訪問不到其他的服務,此時RibbonZookeeperAutoConfiguration還在spring-cloud-zookeeper-discovery包的spring.factories裡面,還是會自動配置,因此我在使用Eureka的時候發現還會走zookeeper的ribbon,這自然就有問題,把這項弄到外面作為開關配置後就可以了,註冊到Eureka時會使用對應的ribbon;
- 7.擴充套件
如果還有其他的服務發現機制,也可以按照這樣的思路去做,這樣的話我們的pom裡面可以引入多種註冊依賴,不需要修改pom檔案了,在工程的spring.factories檔案裡面做多路切換;
- 8.好處
不要修改pom,支援多個註冊中心的切換,但是有個問題,spring.factories檔案也是打進去jar包的,因此它實際上也不算配置項,只不過相比修改pom而言這樣會好一些,這裡有個簡單的思路,比如我們的原始碼不需要修改,我們可以寫一個打包指令碼,例如使用maven打包,那麼打包指令碼肯定是使用mvn命令編譯成jar包,我們可以在打包腳本里面做一個簡單的處理,接受一個引數什麼的,通過引數,在打包腳本里面去修改spring.factories檔案,修改完成之後,我們再執行mvn package命令,這樣的話我們就可以通過命令打出適配不同的註冊中心的jar包了,這裡我自己實現的是ZK,Eureka和k8三種環境的註冊切換機制,剛剛提到指令碼是一個思路,我也還沒做,不過上面的問題要完全做好依賴的東西很多,在第九點說明
- 9.難點
比如我們註冊到Eureka,我們引入的是
org.springframework.cloud
spring-cloud-starter-eureka
他會引入
org.springframework.cloud
spring-cloud-netflix-eureka-client
我們要修改的jar包是spring-cloud-netflix-eureka-client,這裡我們就需要自己封裝一下spring-cloud-netflix-eureka-client再引用,否則其他人可能引用的就是沒有修改的spring-cloud-netflix-eureka-client,可以修改這個jar,然後重新命名放到私服,供團隊一起使用,另外我們直接使用 spring-cloud-starter-eureka也會有問題,因為這個會引入原始的spring-cloud-netflix-eureka-client,我們必須手動排除,但是這部穩妥,最好的辦法是我們改造上面這兩個包,比如改造spring-cloud-starter-eureka為myCompany-spring-cloud-starter-eureka ,在這個包的pom裡面排除對原始spring-cloud-netflix-eureka-client的依賴,引入對myCompany-spring-cloud-netflix-eureka-client的依賴,然後開發過程中,就只需要引入myCompany-spring-cloud-starter-eureka即可,對ZK也是一樣,需要改造兩個包,這裡稍微有點麻煩。
相關推薦
[SpringCloud-Eureka] 使用spring.factories機制來實現註冊中心相容Eureka和Zookeeper
使用SpringBoot開發微服務時,需要通過註冊中心來實現服務之間的發現機制,Eureka和Zookeeper都是常用的 註冊中心框架,我們可以選擇其中之一,現在面臨一個特殊的需求,我們同時存在Eur
Spring Cloud Eureka 服務關閉但是未從註冊中心刪除 自我保護機制,以及如何關閉自我保護機制的辦法
自我保護背景 首先對Eureka註冊中心需要了解的是Eureka各個節點都是平等的,沒有ZK中角色的概念, 即使N-1個節點掛掉也不會影響其他節點的正常執行。 預設情況下,如果Eureka Server在一定時間內(預設90秒)沒有接收到某個微服務例項的心跳,Eure
Spring Cloud Eureka 服務關閉但是未從註冊中心刪除 自我保護機制
背景:由於Eureka擁有自我保護機制,當其登錄檔裡服務因為網路或其他原因出現故障而關停時,Eureka不會剔除服務註冊,而是等待其修復。這是AP的一種實現。 為了讓其有精準的 CP健康檢查,可以採取讓其剔除不健康節點。 server端: eureka.server.
跟著辛星用PHP的反射機制來實現插件
red 實現 track 這一 列表 each 方法 fun 繼承 我的博文的前一篇解說了PHP的反射機制是怎麽回事,假設讀者還不清楚反射機制,能夠搜索下或者看我的博文,都是不錯的選擇。我們開始解說一下怎麽用PHP來實現插件機制。所謂插件機制。就是我們定義
[SpringBoot]深入淺出剖析SpringBoot中Spring Factories機制
prop array enume etc getc ogg 屬性 mes 配置文件 微信號:GitShare微信公眾號:愛折騰的稻草如有問題或建議,請在公眾號留言[1]前續為幫助廣大SpringBoot用戶達到“知其然,更需知其所以然”的境界,作者將通過SpringBoot
業余草 SpringCloud 教程 | 第一篇: 服務的註冊與發現Eureka(Finchley版本)
只需要 版本控制 aps 選擇 framework 電腦 右鍵 org -c 一、spring cloud簡介 鑒於《史上最簡單的Spring Cloud教程》很受讀者歡迎,再次我特意升級了一下版本,目前支持的版本為Spring Boot版本2.0.3.RELEASE,S
SpringCloud --Eureka叢集搭建(高可用服務註冊中心)
Eureka是Spring Cloud框架裡的核心服務, 幾乎每個服務都依賴它。 所以要建立多個Eureka例項程序, 即使其中一個程序掛了, 註冊中心功能仍然正常執行。為了實現高可用,必須叢集 增加Eureka服務註冊中心配置檔案: application-pe
手把手教你搭建springCloud--註冊中心使用eureka
此文章寫的相對比較簡便,主要是為了方便新手開發,如果將所有內容一股腦全放出來,反而增加了新手開發的複雜度,個人認為這樣通俗易懂,我們都是先將服務搭建起來之後再去了解其中的技術要點 如果需要已經搭建好的專案,去這裡下載:https://download.csdn.net/down
使用Spring的Pageable來實現分頁查詢
1.匯入包: import org.springframework.data.domain.Pageable; 2.測試類: @Test public void whenQuerySeccess() throws Exception{ mockM
搭建SpringCloud註冊中心(Eureka)之消費者和服務提供者
一、前言 使用rpc遠端呼叫技術(SpringCloud)搭建如下圖,其中所用到的技術有maven、eureka、ribbon、SpringBoot等 二、準備環境 作業系統:win7 JDK:1.8 三、搭建SpringCloud註冊中心(Eureka)之服務提供者
搭建SpringCloud註冊中心(Eureka)
一 、SpringCloud介紹 Spring Cloud Config 是配置管理工具包,讓你可以把配置放到遠端伺服器,幾種化管理叢集配置,目前支援本地儲存,Git以及Subversion。 Eureka 雲端服務發現,一個基於 REST 的服務,用於定位服務,以實現雲端中間層服務發現
利用spring的AOP來實現Redis快取
為什麼使用Redis 資料查詢時每次都需要從資料庫查詢資料,資料庫壓力很大,查詢速度慢,因此設定快取層,查詢資料時先從redis中查詢,如果查詢不到,則到資料庫中查詢,然後將資料庫中查詢的資料放到redis中一份,下次查詢時就能直接從redis中查到,不需要查
Spring Cloud(一)註冊中心Eureka
Eureka Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模組來實現服務註冊和發現。Eureka 採用了 C-S 的設計架構。Eureka Server 作為服務註冊功能的伺服器,它是服務註冊中心。而系統中的其他微服務,使用 Eureka 的
SpringCloud(1) Eureka註冊中心 —— 服務發現和服務註冊
SpringBoot 2.0+ SpringCloud Eureka註冊中心 —— 服務發現和服務註冊 **服務發現:**服務發現是微服務基礎架構的關鍵原則之一。試圖著手配置每個客戶端或某種格式的約定可以說是非常困難的和非常脆弱的。Eureka是Netflix服
[SpringBoot] 利用spring.factories機制載入Bean
通常我們需要註冊一個bean會使用註解的形式,比如@Component註解,但是在閱讀原始碼的時候我們發現一些bean上面並沒有 該註解或者其他註冊為bean的註解,甚至沒有任何註解,這就納悶了,仔細發現它用到了spring.factories機制。 在zuul
菜鳥學Spring Cloud——建立註冊中心(Eureka)
文章目錄扯一扯軟體環境步驟效果下集預告 扯一扯 以下內容將引起極度舒適,請在女朋友的陪同下觀看。什麼?你沒有女朋友?哦,不好意思,我忘了,程式設計師是沒有女朋友的。那就好好學習吧,女朋友總會有的。 軟體環境 Windows 10 JDK 1.8 IDEA 20
SpringBoot2.0 + SpringCloud Eureka搭建高可用註冊中心(Eureka之二)
上一篇中提到用SpringBoot2.0+Eureka搭建服務註冊中心和服務提供者,詳情參考: https://www.cnblogs.com/SysoCjs/p/10127448.html 現在講一下SpringCloud+Eureka搭建高可用註
SpringCloud筆記(二)高可用註冊中心的實現
目錄 1、要實現的拓撲 2、eureka-sever01和eureka-sever02 3、啟動服務提供者 3.1 pom.xml 3.2 application.yml 3.3 業務類 4、啟動服務消費者 4.1 pom.xml 與服務提供者相同 4.2 a
SpringCloud服務註冊中心比較:Consul vs Zookeeper vs Etcd vs Eureka
這裡就平時經常用到的服務發現的產品進行下特性的對比,首先看下結論: Feature Consul zookeeper etcd euerka 服務健康檢查 服務狀態,記憶體,硬碟等 (弱)長連線,keepalive 連線心跳 可配支援 多資料中心
【SpringCloud Greenwich版本】第一章:服務註冊中心(eureka)
一、SpringCloud版本 本文介紹的Springboot版本為2.1.1.RELEASE,SpringCloud版本為Greenwich.RC1,JDK版本為1.8,整合環境為IntelliJ IDEA 二、Eureka服務端介紹 要在專案中包含Eureka伺服器,請使用組