spring-cloud-eureka服务注册与发现
上圖簡要描述了Eureka的基本架構,由3個角色組成:
- Eureka Server:提供服務注冊和發現
- Service Provider:服務提供方,將自身服務注冊到Eureka,從而使服務消費方能夠找到
- Service Consumer:服務消費方,從Eureka獲取注冊服務列表,從而能夠消費服務。
通過spring boot 搭建 Eureka-Server?
1.pom文件引入依賴,在SpringBoot(2.0.1)項目的基礎上添加以下依賴
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Finchley.SR3</spring-cloud.version></properties><dependencyManagement><dependencies><dependency><!-- SpringCloud 所有子項目 版本集中管理. 統一所有SpringCloud依賴項目的版本依賴--><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><plugins><plugin><!-- SpringBoot 項目打jar包的Maven插件 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>2.?配置文件application.yml
server:port: 7001# eureka注冊中心,不會盲目清楚已經注冊的服務列表內的任何微服務,這是他的自我保護機制, # 當微服務長時間沒有客戶端請求,即沒有心跳,便會啟動自我保護, eureka:instance: #Eureka實例名,集群中根據這里相互識別hostname: eureka7001.comclient:registerWithEureka: false #表示是否注冊Eureka服務器,因為自身作為服務注冊中心,所以為falsefetchRegistry: false #是否從eureka上獲取注冊信息,因為自身作為服務注冊中心,所以為falseserviceUrl: #http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #集群版defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/?3. 主啟動類注解
@EnableEurekaServer // Eureka服務端注解 @SpringBootApplication public class EurekaServerApp {public static void main(String[] args) {SpringApplication.run(EurekaServerApp.class,args);log.info("服務啟動成功");} }? 如上便完成了Eureka-Server的基本配置,接下去創建Service Provider?
1.pom文件引入依賴與上面保持一致即可。?
2.?配置文件application.yml
server:port: 8001spring:application:name: cloud-provider #服務注冊到Eureka上使用的名稱eureka:client:service-url: # 集群情況下如下,如果是單機版,只需要配置單機版Eureka地址defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ instance:instance-id: cloud-provider-8001prefer-ip-address: true #訪問路徑顯示IP地址info: # 在Eureka上點擊服務時會跳轉到個404頁面,可配置這里讓他跳轉到服務簡介的一個頁面,信息如下配置app.name: wuzzcompany.name: www.wuzz.combuild.artifactId: server-providerbuild.version: 1.03. 主啟動類注解?
@EnableEurekaClient @SpringBootApplication @EnableDiscoveryClient public class EurekaServerProviderApp {private final static Logger log = LoggerFactory.getLogger(EurekaServerProviderApp.class);public static void main(String[] args) {SpringApplication.run(EurekaServerProviderApp.class,args);log.info("服務啟動成功");} }如上便完成了Eureka-Server的基本配置,這樣Eureka的服務的基本架構也基本完成。這里可以添加一個服務發現的Controller。
@RestController public class TestController {@Autowired//服務發現private DiscoveryClient client;@GetMapping("/hello")public String helloEureka(){return "Hello Eureka Provider";}/*** 服務發現* @return*/@RequestMapping(value ="/discovery",method= RequestMethod.GET)public Object discovery() {List<String> list = client.getServices();List<ServiceInstance> instances = client.getInstances("");for(ServiceInstance instance : instances) {System.out.println(instance.getHost());}return this.client;} }? 下面來說說Eureka的一些基本問題:
為什么要有自我保護機制:
? ? ? ? 眾所周知,Eureka在CAP理論當中是屬于AP , 也就說當產生網絡分區時,Eureka保證系統的可用性,但不保證系統里面數據的一致性, 舉個例子。當發生網絡分區的時候,Eureka-Server和client端的通信被終止,server端收不到大部分的client的續約,這個時候,如果直接將沒有收到心跳的client端自動剔除,那么會將可用的client端剔除,這不符合AP理論,所以Eureka寧可保留也許已經宕機了的client端 , 也不愿意將可以用的client端一起剔除。 從這一點上,也就保證了Eureka程序的健壯性,符合AP理論。
自我保護模式正是一種針對網絡異常波動的安全保護措施,使用自我保護模式能使Eureka集群更加的健壯、穩定的運行。
默認情況下,當eureka server在一定時間內沒有收到實例的心跳,便會把該實例從注冊表中刪除(默認是90秒),但是,如果短時間內丟失大量的實例心跳,便會觸發eureka server的自我保護機制,比如在開發測試時,需要頻繁地重啟微服務實例,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka注冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理界面看到Renews threshold和Renews(last min),當后者(最后一分鐘收到的心跳數)小于前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:
EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.
從警告中可以看到,eureka認為雖然收不到實例的心跳,但它認為實例還是健康的,eureka會保護這些實例,不會把它們從注冊表中刪掉。
該保護機制的目的是避免網絡連接故障,在發生網絡故障時,微服務和注冊中心之間無法正常通信,但服務本身是健康的,不應該注銷該服務,如果eureka因網絡故障而把微服務誤刪了,那即使網絡恢復了,該微服務也不會重新注冊到eureka server了,因為只有在微服務啟動的時候才會發起注冊請求,后面只會發送心跳和服務列表請求,這樣的話,該實例雖然是運行著,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護注冊表中的信息,不在注銷任何微服務,當網絡故障恢復后,eureka會自動退出保護模式。自我保護模式可以讓集群更加健壯。
但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務實例沒有被刪除,這時請求有可能跑到舊的實例中,而該實例已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置文件中加上如下配置即可:
eureka.server.enable-self-preservation=false
但在生產環境,不會頻繁重啟,所以,一定要把自我保護機制打開,否則網絡一旦終端,就無法恢復。
當然關于自我保護還有很多個性化配置,這里不詳細說明
因此Eureka Server可以很好的應對因網絡故障導致部分節點失聯的情況,而不會像ZK那樣如果有一半不可用的情況會導致整個集群不可用而變成癱瘓
作為服務注冊中心,Eureka比Zookeeper好在哪里:
著名的CAP理論指出,一個分布式系統不可能同時滿足C(一致性)、A(可用性)和P(分區容錯性)。由于分區容錯性在是分布式系統中必須要保證的,因此我們只能在A和C之間進行權衡。在此Zookeeper保證的是CP, 而Eureka則是AP。
Zookeeper保證CP
當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接受服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但是zk會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集群都是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因網絡問題使得zk集群失去master節點是較大概率會發生的事,雖然服務能夠最終恢復,但是漫長的選舉時間導致的注冊長期不可用是不能容忍的。
Eureka保證AP
Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊或時如果發現連接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka還有一種自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:?
1. Eureka不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務?
2. Eureka仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點依然可用)?
3. 當網絡穩定時,當前實例新的注冊信息會被同步到其它節點中
因此, Eureka可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像zookeeper那樣使整個注冊服務癱瘓。
Eureka Server集群宕機后,客戶端是否可用?
情景一
Eureka Client 啟動的時候,會主動去全量獲取一次注冊信息,如果這個時候Eureka Server集群
已經宕機,那么Eureka Client端是不可用的。
情景二
如果Eureka Client 啟動時全量獲取注冊信息成功,在之后的運行過程當中,Eureka Server集群宕機了
那么這個時候,Eureka Client是不受影響的
?
轉載于:https://www.cnblogs.com/wuzhenzhao/p/9466752.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的spring-cloud-eureka服务注册与发现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无人机上市公司龙头股票
- 下一篇: 新三板原始股能买吗 个人投资者购买渠道