Spring-Cloud-Netflix-Eureka注冊中心


概述

  1. eureka是Netflix的子模塊之一,也是一個核心的模塊
  2. eureka里有2個組件:
    一個是EurekaServer(一個獨立的項目) 這個是用於定位服務以實現中間層服務器的負載平衡和故障轉移
    一個便是EurekaClient(我們的微服務) 它是用於與Server交互的,可以使得交互變得非常簡單:只需要通過服務標識符即可拿到服務
  3. Eureka負責管理、記錄服務提供者的信息
  4. 服務調用者無需自己尋找服務,而是把自己的需求告訴Eureka,然后Eureka會把符合你需求的服務告訴你。
  5. 類似家政中心,物業

Netflix-Eureka與SpringCloud的關系

Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務注冊和發現

Eureka原理

  1. Eureka:就是服務注冊中心(可以是一個集群),對外暴露自己的地址
  2. 提供者:啟動后向Eureka注冊自己信息(地址,提供什么服務)
  3. 消費者:向Eureka訂閱服務,Eureka會將對應服務的所有提供者地址列表發送給消費者,並且定期更新
  4. 心跳(續約):提供者定期通過http方式向Eureka刷新自己的狀態,會監聽有沒有定期更新,如果長時間沒有心跳,就會自動把該服務移除
    在這里插入圖片描述

Eureka使用

  1. 在之前工程中添加一個子模塊名稱為Eureka3000
    在這里插入圖片描述
  2. 在總父工程添加SpringCloud的依賴集中管理
    在這里插入圖片描述
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  1. 在Eureka3000的子模塊中添加依賴
    在這里插入圖片描述
	<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
  1. 在resources當中創建配置文件application.yml
    在這里插入圖片描述
server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: localhost
  1. 創建啟動類,並在啟動器上添加EnableEurekaServer注解
    在這里插入圖片描述
@SpringBootApplication
@EnableEurekaServer
public class Eureka3000App {
    public static void main(String[] args) {
        SpringApplication.run(Eureka3000App.class, args);
    }
}

  1. 直接啟動會報錯com.sun.jersey.api.client.ClientHandlerException
    原因:

Eureka做為注冊中心, 做為服務的管理,它不能掛掉, 如果它掛掉,整個服務全部訪問不了
因此Eureka也要搭建集群多台Eureka服務, 集群之間要進行相互之間通信,通信靠的就是Eureka-client
Eureka是一個服務端, 也是一個客戶商, 以后相互注冊,現在沒有其它的可注冊,所以就會報ClientException

解決方案:不讓它做為客戶端注冊,在application.yml添加如下配置
在這里插入圖片描述

client:
    registerWithEureka: false #不把自己作為一個客戶端注冊到自己身上
    fetchRegistry: false  #不需要從服務端獲取注冊信息(因為在這里自己就是服務端,而且已經禁用自己注冊了)
    serviceUrl: #微服務要注冊到的地址.
        #http://localhost:3000/eureka
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
  1. 運行后,在瀏覽器地址欄直接訪問http://localhost:3000/
    在這里插入圖片描述
    發現啟動后,還沒有服務進行注冊。

服務注冊:

  1. 在user工程中添加eureka客戶端相關依賴
    在這里插入圖片描述
<!--Eureka的客戶端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  1. 在啟動器上添加注解@EnableEurekaClient
    在這里插入圖片描述
@EnableEurekaClient
  1. 創建application.yml配置文件,配置eureka的服務端地址
    在這里插入圖片描述
server:
  port: 5000
eureka:
  client:
    serviceUrl:
      #eureka服務端提供的注冊地址 參考服務端配置的這個路徑
      defaultZone: http://localhost:3000/eureka
  instance:
    instance-id: user-1 #此實例注冊到eureka服務端的唯一的實例ID
    prefer-ip-address: true #是否顯示IP地址
    #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認為30 秒 (與下面配置的單位都是秒)
    leaseRenewalIntervalInSeconds: 10
    #Eureka服務器在接收到實例的最后一次發出的心跳后,需要等待多久才可以將此實例刪除,默認為90秒
    leaseExpirationDurationInSeconds: 30

spring:
  application:
    name: client-user #此實例注冊到eureka服務端的name
  1. 注冊goods,和上面步驟一樣,注意改一下的地方
    在這里插入圖片描述
  2. 啟動Eureka3000,user,goods注冊到注冊中心
    在這里插入圖片描述
    可以看到已經注冊成功

常用配置:

  1. 服務注冊

服務提供者在啟動時,會檢測配置屬性中的:eureka.client.register-with-erueka=true參數是否正確,
事實上默認就是true。如果值確實為true,則會向EurekaServer發起一個Rest請求

  1. 獲取服務列表

當服務消費者啟動是,會檢測eureka.client.fetch-registry=true參數的值,如果為true, 則會從Eureka
Server服務的列表只讀備份,然后緩存在本地。並且每隔30秒會重新獲取並更新數據。
eureka.client.registry-fetch-interval-seconds: 5 生產環境中,我們不需要修改這個值。

  1. 服務續約
eureka:
  instance:
    lease-expiration-duration-in-seconds: 90 :服務續約(renew)的間隔,默認為30秒
    lease-renewal-interval-in-seconds: 30 :服務失效時間,默認值90秒

在注冊服務完成以后,服務提供者會維持一個心跳
也就是說,默認情況下每個30秒服務會向注冊中心發送一次心跳,證明自己還活着。如果超過90秒沒有發送心跳
EurekaServer就會認為該服務宕機,會從服務列表中移除,這兩個值在生產環境不要修改,默認即可。

  1. 失效剔除

有些時候,我們的服務提供方並不一定會正常下線,可能因為內存溢出、網絡故障等原因導致服務無法正常工作 Eureka
Server需要將這樣的服務剔除出服務列表。因此它會開啟一個定時任務,每隔60秒對所有失效的服務(超過90秒未響應)進行剔除
可以通過eureka.server.eviction-interval-timer-in-ms參數對其進行修改,單位是毫秒

  1. 自我保護機制

當把一個服務停掉后, 並不會立馬從服務列表當中移除,默認是90秒清除一次
有可以注冊中心和微服務之間出現了網絡波動,網絡不好,沒有收到心跳,有可能是網絡不好,但是微服務還在,所以它不會立馬把服務給移除
當15分鍾內85%的心跳都沒有正常心跳,那么eureka認為客戶端與注冊中心出現了網絡問題,此時會出現以下情況:
1.Eureka不再從注冊列表中移除因為長時間沒有收到的心跳而過期的服務
2.Eureka仍然能夠接收服務的注冊和查詢請求,但是不會被同步到其它節點上
3.當網絡穩定后,當前實例新注冊的信息會被同步到其它節點上

CAP定理(了解)

  1. 什么是CAP定理

CAP定理又稱CAP原則, 指的是在一個分布式系統中,Consistency(一致性)、
Availability(可用性)、Partition tolerance(分區容錯性), 最多只能同時三個特性中的兩個,三者不可兼得

  1. Consistency (一致性)

“all nodes see the same data at the same time”,
即更新操作成功並返回客戶端后,所有節點在同一時間的數據完全一致,這就是分布式的一致性。

  1. Availability(可用性)

可用性指“Reads and writes always succeed” 即服務一直可用,而且是正常響應時間。
好的可用性主要是指系統能夠很好的為用戶服務,不出現用戶操作失敗或者訪問超時等用戶體驗不好的情況

  1. Partition tolerance(分區容錯性)

大多數分布式系統都分布在多個子網絡。每個子網絡就叫做一個區
分區容錯的意思是,區間通信可能失敗。比如,一台服務器放在本地,另一台服務器放在外地(可能是外省,甚至是外國),這就是兩個區,它們之間可能無法通信
兩台跨區的服務器。Server1 向 Server2 發送一條消息,Server2 可能無法收到。系統設計的時候,必須考慮到這種情況.
一般來說,分區容錯無法避免,因此可以認為 CAP 的 P 總是成立
即分布式系統在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一致性或可用性的服務。
分區容錯性要求能夠使應用雖然是一個分布式系統,而看上去卻好像是在一個可以運轉正常的整體。

  1. Consistency 和 Availability 的矛盾

如果保證 Server2 的一致性,那么 Server1 必須在寫操作時,鎖定 Server2
的讀操作和寫操作。只有數據同步后,才能重新開放讀寫。鎖定期間,Server2 不能讀寫,沒有可用性 如果保證 Server2的可用性,那么勢必不能鎖定 Server2,所以一致性不成立

  1. 取舍策略
    CAP三個特性只能滿足其中兩個,那么取舍的策略就共有三種:
    1.CA without P:

如果不要求P(不允許分區),則C(強一致性)和A(可用性)是可以保證的。
但放棄P的同時也就意味着放棄了系統的擴展性,也就是分布式節點受限,沒辦法部署子節點, 這是違背分布式系統設計的初衷的。

2.CP without A:

如果不要求A(可用),相當於每個請求都需要在服務器之間保持強一致,而P(分區)會導致同步時間無限延長
(也就是等待數據同步完才能正常訪問服務)
一旦發生網絡故障或者消息丟失等情況,就要犧牲用戶的體驗,等待所有數據全部一致了之后再讓用戶訪問系統。

3.AP wihtout C:

要高可用並允許分區,則需放棄一致性。 一旦分區發生,節點之間可能會失去聯系,為了高可用,每個節點只能用本地數據提供服務
而這樣會導致全局數據的不一致性。
搶購商品時,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品准備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在
A(可用性)方面保證系統可以正常的服務,然后在數據的一致性方面做了些犧牲,雖然多少會影響一些用戶體驗,但也不至於造成用戶購物流程的嚴重阻塞。

沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的才是最好的


免責聲明!

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



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