SpringCloud Netflix Eureka(服務注冊/發現)


⒈Eureka是什么?

  Eureka是Netflix的一個子模塊,也是核心模塊之一,Eureka是一個基於REST的服務,用於定位服務以實現雲端中間層服務發現和故障轉移,服務注冊與發現對於微服務架構來說是非常重要的,有了服務注冊與發現,只需要使用服務的標識符就可以訪問到服務,而不需要修改服務調用的配置文件,功能類似於Dubbo的注冊中心,例如Zookeeper。

  SpringCloud封裝了Netflix公司開發的Eureka模塊來實現服務注冊與發現,Eureka采用了C/S設計架構,Eureka Server作為服務注冊功能的服務器,它是服務注冊中心。而系統中的其他微服務,使用Eureka Client連接到Eureka Server並維持心跳連接,這樣系統的維護人員就可以通過Eureka Server來監控系統中的各個微服務是否正常運行,SpringCloud的一些其他模塊(例如Zuul)就可以通過Eureka Server來發現系統中的其他微服務,並執行相關的邏輯。

  Eureka包含兩個組件,Eureka Server和Eureka Client。

  Eureka Server提供服務注冊服務。各個微服務啟動后,會在Eureka Server中進行注冊,這樣Eureka Server中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。

  Eureka Client是一個Java客戶端,用於簡化Eureka Server的交互,客戶端同時也具備一個內置的-使用輪詢(round-robin)負載算法的負載均衡器。在應用啟動后,Eureka Client將會向Eureka Server發送心跳(默認周期30秒),如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server將會從服務的注冊列表中移除該服務節點(默認90秒)。

⒉Eureka三大角色

  ①Eureka Server  -  提供服務注冊與發現

  ②Service Provider(服務提供者)  -  將自身服務注冊到Eureka Server,從而使服務消費者能夠找到。

  ③Service Consumer(服務消費者)  -  從Eureka Server中獲取服務列表,從而能夠消費服務。

⒊示例

  請訪問我的示例文章地址:https://www.cnblogs.com/fanqisoft/p/10357598.html

⒋一些Eureka配置擴展

  ①修改在Eureka管理界面中的主機名稱

1 eureka:
2   instance:
3     instance-id:  #設置主機名稱

  ②修改在Eureka管理界面中的主機ip是否顯示

1 eureka:
2   instance:
3     prefer-ip-address: true #主機ip是否顯示

  ③修改在Eureka管理界面中的主機info詳細信息

    ⅰ添加pom依賴  

1         <dependency>
2             <groupId>org.springframework.boot</groupId>
3             <artifactId>spring-boot-starter-actuator</artifactId>
4         </dependency>

    ⅱ父工程pom文件中添加構建的Build信息(可選)

    ⅲ在配置文件中添加info配置信息

⒌Eureka自我保護

  

   ①導致原因:

  某時刻某一個微服務不可用了,Eureka不會立刻清理,依舊會對該微服務的信息進行保存。

  ②什么是自我保護模式?

  默認情況下,如果Eureka Server在一定時間內沒有收到某個微服務實例的心跳,Eureka Server將會注銷該實例(默認90秒),但是當網絡分區故障發生時,微服務與Eureka Server之間無法正常通信,那么以上的行為可能就變得非常危險了,因為這個微服務本身其實是健康的,此時不應該注銷這個微服務。

  Eureka通過“自我保護模式”來解決這個問題,當Eureka Server節點在短時間內丟失過多客戶端時(可能這些客戶端發生了網絡分區故障),那么當前Eureka Server節點就會進入自我保護模式,一旦進入該模式,Eureka Server就會保護服務注冊表中的信息,不再刪除服務注冊表中的數據,也就是說不會注銷任何微服務,當網絡故障恢復后,該Eureka Server節點就會自動退出自我保護模式。

  在自我保護模式中,Eureka Server會保護服務注冊表中的信息,不會注銷任何服務實例,當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式,它的設計哲學就是寧可保留錯誤的服務注冊信息,也不盲目注銷任何可能健康的服務實例。

  自我保護模式是一種應對網絡異常的安全保護措施,它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留)也不盲目注銷任何可能健康的微服務。使用自我保護模式,可以讓Eureka集群更加健壯、穩定。

  在SpringCloud中,可以使用eureka.server.enable-self-preservation=false來禁用自我保護模式(不推薦)。

⒍Eureka服務發現

  ①在服務消費者主程序啟動類上添加@EnableDiscoveryClient注解

 1 package cn.coreqi;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 6 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 7 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 8 import org.springframework.context.annotation.Bean;
 9 import org.springframework.web.client.RestOperations;
10 import org.springframework.web.client.RestTemplate;
11 
12 @SpringBootApplication
13 //@EnableDiscoveryClient  //開啟服務發現功能
14 @EnableDiscoveryClient  //開啟服務發現功能
15 public class SpringbootcloudserviceconsumerApplication {
16 
17     public static void main(String[] args) {
18         SpringApplication.run(SpringbootcloudserviceconsumerApplication.class, args);
19     }
20 
21     @Bean
22     @LoadBalanced   //使用負載均衡機制
23     public RestOperations restTemplate(){
24         return new RestTemplate();
25     }
26 
27 }

  ②控制器添加相關代碼

 1 package cn.coreqi.controller;
 2 
 3 import cn.coreqi.entities.User;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.cloud.client.ServiceInstance;
 6 import org.springframework.cloud.client.discovery.DiscoveryClient;
 7 import org.springframework.web.bind.annotation.GetMapping;
 8 import org.springframework.web.bind.annotation.RestController;
 9 import org.springframework.web.client.RestOperations;
10 import java.util.List;
11 
12 @RestController
13 public class UserController {
14     @Autowired
15     private RestOperations restTemplate;
16     
17     @Autowired
18     private DiscoveryClient client;
19 
20     @GetMapping("/userno2")
21     public String discovery(){
22         List<String> list = client.getServices();
23         System.out.println("*****" + list);
24         List<ServiceInstance> serviceList = client.getInstances("USER-PROVIDER");
25         for (ServiceInstance item : serviceList){
26             System.out.println(item.getServiceId() + "\t" + item.getHost() + "\t" + item.getPort() + "\t" + item.getUri());
27         }
28         return "success";
29     }
30     
31     @GetMapping("/userno1")
32     public User getUsersFirst(){
33         User[] users = restTemplate.getForObject("http://user-provider/users",User[].class);
34         return users[0];
35     }
36 }

⒎Eureka集群配置

    為了更直觀的顯示集群效果,做了一下域名關系映射。

    

  ①Eureka Server集群搭建

    Ⅰ新建幾個Eureka Server項目(略)

    Ⅱ在這幾個Eureka Server項目的主程序啟動類上添加@EnableEurekaServer注解(以一個為例)

 1 package cn.coreqi;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 6 
 7 @SpringBootApplication
 8 @EnableEurekaServer
 9 public class EurekaServerApplication {
10 
11     public static void main(String[] args) {
12         SpringApplication.run(EurekaServerApplication.class, args);
13     }
14 
15 } 

    Ⅲ分別修改它們的配置文件(以兩個為例)   

 1 server:
 2   port: 8761
 3 eureka:
 4   instance:
 5     hostname: eureka-server1 #Eureka服務端實例名稱
 6   client:
 7     register-with-eureka: false #是否向注冊中心注冊自己
 8     fetch-registry: false #是否從Eureka上獲取服務的注冊信息,自己就是注冊中心,本身職責就是維護服務實例,並不需要去檢索服務
 9     service-url:
10       defaultZone: http://eureka8762.com:8762/eureka/,http://eureka8763.com:8763/eureka/  #設置與Eureka Server交互的地址(查詢服務、注冊服務等)
 1 server:
 2   port: 8762
 3 eureka:
 4   instance:
 5     hostname: eureka-server2 #Eureka服務端實例名稱
 6   client:
 7     register-with-eureka: false #是否向注冊中心注冊自己
 8     fetch-registry: false #是否從Eureka上獲取服務的注冊信息,自己就是注冊中心,本身職責就是維護服務實例,並不需要去檢索服務
 9     service-url:
10       defaultZone: http://eureka8761.com:8761/eureka/,http://eureka8763.com:8763/eureka/  #設置與Eureka Server交互的地址(查詢服務、注冊服務等)

    總結一下不同:

      1.端口不同

      2.eureka.instance.hostname  不可重名

      3.eureka.client.service-url.defaultZone  手牽手模式,把除自己以外的集群內的其它Eureka Server全部配置進來

  ②Eureka Client連接Eureka Server集群

    Ⅰ新建一個Eureka Client項目用作服務提供者(必須引入Web模塊,否則注冊服務后項目會自動停止)

1         <dependency>
2             <groupId>org.springframework.cloud</groupId>
3             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
4         </dependency>
5         <dependency>
6             <groupId>org.springframework.boot</groupId>
7             <artifactId>spring-boot-starter-web</artifactId>
8         </dependency>

    Ⅱ在主程序啟動類上添加@EnableEurekaClient注解

 1 package cn.coreqi;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 6 
 7 @SpringBootApplication
 8 @EnableEurekaClient
 9 public class ServiceProviderApplication {
10 
11     public static void main(String[] args) {
12         SpringApplication.run(ServiceProviderApplication.class, args);
13     }
14 
15 }

    Ⅲ修改配置文件

 1 server:
 2   port: 8001
 3 spring:
 4   application:
 5     name: user-provider
 6 eureka:
 7   instance:
 8     prefer-ip-address: true #注冊服務的時候使用服務的ip地址
 9   client:
10     service-url:
11       defaultZone: http://eureka8761.com:8761/eureka/,http://eureka8762.com:8762/eureka/,http://eureka8763.com:8763/eureka/

      總結一下:

        1.eureka.client.service-url.defaultZone:將集群內所有的Eureka Server全部配置進來

⒏數據的有關擴展

  傳統的關系型數據庫(SqlServer、MySQL、Oracle)  =》  ACID

  非關系型數據庫(Redis、MongDB)  =》  CAP

 

  ACID:

    A(Atomicity)原子性:事務中的所有操作要么都成功執行,要么什么都不做。

    C(Consistency)一致性:數據庫要一直處於一致的狀態,事務的運行不會改變數據庫原本的一致性約束。

    I(Isolation)獨立性:並發的事務之間不會相互影響。

    D(Durability)持久性:一旦事務提交,它所做的修改將會永久的保存在數據庫上,即使宕機也不會丟失。

 

  CAP:

    C(Consistency)強一致性

    A(Availability)可用性

    P(Partition tolevance)分區容錯性

 

  CAP的3進2原則:即任何一個分布式系統不可能同時滿足CAP,只能3選2。

  CA:單點集群,滿足一致性、可用性的系統,通常在可擴展性上不太強大。

  CP:滿足一致性、分區容忍性的系統,通常性能不是特別高。

  AP:滿足可用性、分區容忍性的系統,通常可能對一致性要求低一些。

  因為當前的網絡硬件肯定會出現延遲丟包等問題,因此,分布式系統中,分區容忍性(P)是我們必須要實現的,所以我們只能在一致性(CP)和可用性(AP)之間權衡。

  天貓雙11保證的是AP原則。

 

 

Zookeeper保證CP

  當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鍾以前的注冊信息,但不能接受服務直接Down掉不可用,也就是說,服務注冊功能對可用性的要求要高於一致性,但是Zookeeper會出現這樣一種情況,當主節點(master)因為網絡故障與其它節點失去聯系時,剩余節點將會重新進行主節點的選舉,選舉的時間太長,一般在30s~120s之間,且選舉的過程中整個Zookeeper集群都是不可用的,這就導致了在選舉期間Zookeeper的注冊服務是癱瘓的。

  在雲部署的環境下,因網絡問題使得Zookeeper集群失去主節點(master)是較大概率會發生的事情,雖然服務能夠最終恢復,但是漫長的選舉時間導致注冊服務長時間不可用是不能容忍的。

 

Eureka保證AP

  Eureka在設計時就優先保證了可用性,Eureka各個節點都是平等的,無論多少個節點掛掉都不會影響正常工作的節點,剩余的節點依然可以提供服務注冊和查詢,而Eureka Client在向某個Eureka Server注冊時如果發現連接失敗,則會自動切換至其它節點,只要有一台Eureka Server還在,就能保證注冊服務可用(可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka還有一種自我保護機制,如果在15分鍾內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心之間出現了網路故障,此時會出現以下幾種情況:

    1.Eureka不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務。

    2.Eureka仍然能夠接收新服務的注冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點依然可用)。

    3.當網絡穩定時,當前實例新的注冊信息會被同步到其它節點中。

  因此,Eureka可以很大的應對因網絡故障導致部分節點失去聯系的情況,而不會像Zookeeper那樣使整個注冊服務癱瘓。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM