SpringCloud微服務技術(二)——SpringCloud組件之Eureka

Eureka介紹

Eureka是什麼

Eureka是Netflix的子模塊之一,也是一個核心的模塊,Eureka裏有2個組件,一個是EurekaServer(一個獨立的項目) 這個是用於定位服務以實現中間層服務器的負載平衡和故障轉移,另一個便是EurekaClient(我們的微服務) 它是用於與Server交互的,可以使得交互變得非常簡單:只需要通過服務標識符即可拿到服務。

Eureka與spring-cloud的關係

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

Eureka能做什麼

Eureka 採用了 C-S 的設計架構。Eureka Server 作爲服務註冊功能的服務器,它是服務註冊中心

核心功能點

在這裏插入圖片描述

  • 服務註冊(register):Eureka Client會通過發送REST請求的方式向Eureka Server註冊自己的服務,提供自身的元數據,比如ip地址、端口、運行狀況指標的url、主頁地址等信息。Eureka Server接收到註冊請求後,就會把這些元數據信息存儲在一個雙層的Map中。
  • 服務續約(renew):在服務註冊後,Eureka Client會維護一個心跳來持續通知Eureka Server,說明服務一直處於可用狀態,防止被剔除。Eureka Client在默認的情況下會每隔30秒(eureka.instance.leaseRenewallIntervalInSeconds)發送一次心跳來進行服務續約。
  • 服務同步(replicate):Eureka Server之間會互相進行註冊,構建Eureka Server集羣,不同Eureka Server之間會進行服務同步,用來保證服務信息的一致性。
  • 獲取服務(get registry):服務消費者(Eureka Client)在啓動的時候,會發送一個REST請求給Eureka Server,獲取上面註冊的服務清單,並且緩存在Eureka Client本地,默認緩存30秒(eureka.client.registryFetchIntervalSeconds)。同時,爲了性能考慮,Eureka Server也會維護一份只讀的服務清單緩存,該緩存每隔30秒更新一次。
  • 服務調用:服務消費者在獲取到服務清單後,就可以根據清單中的服務列表信息,查找到其他服務的地址,從而進行遠程調用。Eureka有Region和Zone的概念,一個Region可以包含多個Zone,在進行服務調用時,優先訪問處於同一個Zone中的服務提供者。
  • 服務下線(cancel):當Eureka Client需要關閉或重啓時,就不希望在這個時間段內再有請求進來,所以,就需要提前先發送REST請求給Eureka Server,告訴Eureka Server自己要下線了,Eureka Server在收到請求後,就會把該服務狀態置爲下線(DOWN),並把該下線事件傳播出去。
  • 服務剔除(evict):有時候,服務實例可能會因爲網絡故障等原因導致不能提供服務,而此時該實例也沒有發送請求給Eureka Server來進行服務下線,所以,還需要有服務剔除的機制。EurekaServer在啓動的時候會創建一個定時任務,每隔一段時間(默認60秒),從當前服務清單中把超時沒有續約(默認90秒,eureka.instance.leaseExpirationDurationInSeconds)的服務剔除。
  • 自我保護:既然Eureka Server會定時剔除超時沒有續約的服務,那就有可能出現一種場景,網絡一段時間內發生了異常,所有的服務都沒能夠進行續約,Eureka Server就把所有的服務都剔除了,這樣顯然不太合理。所以,就有了自我保護機制,當短時間內,統計續約失敗的比例,如果達到一定閾值,則會觸發自我保護的機制,在該機制下, Eureka Server不會剔除任何的微服務,等到正常後,再退出自我保護機制。自我保護開關(eureka.server.enable- self-preservation: false)

Eureka如何使用

  • 1.在spring-cloud項目裏面加入依賴
    eureka客戶端:
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

eureka服務端:

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • 2.eureka服務端項目裏面加入以下配置
server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: localhost


  client:
    registerWithEureka: false #不把自己作爲一個客戶端註冊到自己身上
    fetchRegistry: false  #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
  • 3.在spring-boot啓動項目上 加入註解:@EnableEurekaServer 就可以啓動項目了
@EnableEurekaServer
@SpringBootApplication
public class AppEureka {
    public static void main(String[] args) {
        SpringApplication.run(AppEureka.class);

    }
}

如果看見這個圖片,那麼說明你就搭建好了:
在這裏插入圖片描述
這個警告只是說你把他的自我保護機制關閉了

  • 4.Eureka客戶端配置
server:
  port: 6000
eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:3000/eureka/  #eureka服務端提供的註冊地址 參考服務端配置的這個路徑
  instance:
    instance-id: power-1 #此實例註冊到eureka服務端的唯一的實例ID 
    prefer-ip-address: true #是否顯示IP地址
    leaseRenewalIntervalInSeconds: 10 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒)
    leaseExpirationDurationInSeconds: 30 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒

spring:
  application:
    name: server-power #此實例註冊到eureka服務端的name

然後在客戶端的spring-boot啓動項目上 加入註解:@EnableEurekaClient 就可以啓動項目了
在這裏插入圖片描述
這裏我們能看見名字叫server-power的(圖中將其大寫) id爲 power-1的服務 註冊到我們的Eureka上面來了 至此,一個簡單的eureka已經搭建好了。

Eureka和Nginx在負載均衡上對比

Nginx

在這裏插入圖片描述
假設採用輪詢機制,nginx在集羣中的某個服務掛掉之後,再次輪詢到該服務時,瀏覽器會出現刷新,但是一直無法訪問該服務。
第一次刷新
在這裏插入圖片描述
第二次刷新
在這裏插入圖片描述
反覆刷新,上面兩種情況交替出現。
暫停power1服務,刷新瀏覽器
在這裏插入圖片描述

Eureka

而使用Eureka作爲負載均衡,當某個服務掛掉之後,且超時無響應,則會剔除該掛掉的服務。
在這裏插入圖片描述

相關配置

EurekaServer

eureka:
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 4000 #4s清除服務 設置清理間隔

EurekaClient

eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:3000/eureka/  #eureka服務端提供的註冊地址 參考服務端配置的這個路徑
  instance:
    instance-id: power-1 #此實例註冊到eureka服務端的唯一的實例ID
    prefer-ip-address: true #是否顯示IP地址
    leaseRenewalIntervalInSeconds: 1 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒)
    leaseExpirationDurationInSeconds: 3 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒

CAP定理

一致性Consistency

寫操作之後的讀操作,必須返回該值。

可用性Availability

只要收到用戶的請求,服務器就必須給出迴應。

分區容錯性Partition tolerance

大多數分佈式系統都分佈在多個子網絡。每個子網絡就叫做一個區(partition)。分區容錯的意思是,區間通信可能失敗。比如,一臺服務器放在本地,另一臺服務器放在外地(可能是外省,甚至是外國),這就是兩個區,它們之間可能無法通信。

案例說明

在分佈式系統中,分區容錯性必須成立,因爲要保證系統服務之間可以正常通信。
如下例子:
S1 和 S2 是兩臺跨區的服務器,服務器上部署的是相同的系統資源
在這裏插入圖片描述
某條記錄是 v0,用戶向 S1 發起一個寫操作,將其改爲 v1
在這裏插入圖片描述
正常讀取S1服務器上的資源,返回v1
在這裏插入圖片描述
用戶有可能會向S2發起讀取操作,由於s2的值沒有發生變化,因此返回的是v0,所以S1和S2的讀操作不一致,
在這裏插入圖片描述
爲了讓S2的返回值與S1一致,所以我們需要在往S1執行寫操作的時候,讓S1給S2也發送一條消息,要求s2也變成v1
在這裏插入圖片描述
這樣子用戶向s2發起讀操作,就也能得到v1
在這裏插入圖片描述
一致性和可用性,爲什麼不可能同時成立?答案很簡單,因爲可能通信失敗(即出現分區容錯)。
如果保證 S2 的一致性,那麼 S1 必須在寫操作時,鎖定 S2 的讀操作和寫操作。只有數據同步後,才能重新開放讀寫。鎖定期間,S2 不能讀寫,可用性不成立。
如果保證 S2 的可用性,那麼勢必不能鎖定 S2,所以一致性不成立。
綜上所述,S2 無法同時做到一致性和可用性。系統設計時只能選擇一個目標。如果追求一致性,那麼無法保證所有節點的可用性;如果追求所有節點的可用性,那就沒法做到一致性。

Eureka集羣

Eureka集羣原理

  • 服務啓動後向Eureka註冊,Eureka Server會將註冊信息向其他Eureka Server進行同步
  • 當服務消費者要調用服務提供者,則向服務註冊中心獲取服務提供者地址,然後會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。

Eureka集羣配置

  • 1.創建模塊
    在這裏插入圖片描述
    如何聲明集羣環境的server?
    Eureka 的server會把自己的註冊信息與其他的server同步,所以這裏我們不需要註冊到自己身上
    在這裏插入圖片描述
    方便理解集羣 我做了一個域名的映射
    在這裏插入圖片描述

  • 2.Eureka1服務配置
    在這裏插入圖片描述

  • 3.Eureka2服務配置
    在這裏插入圖片描述

  • 4.Eureka3服務配置
    在這裏插入圖片描述

  • 5.客戶端配置
    在這裏插入圖片描述

  • 6.啓動所有服務,查看
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    由此可看出客戶端服務只配置了eureka1這一個註冊中心,但是eureka2,eureka3同樣可以發現此客戶端服務。

Eureka的高可用體現

上例停止eureka2這個服務後,eureka1,eureka3可以正常註冊服務
上例停止eureka2,eureka3兩個服務後,eureka1可以正常註冊服務
將上例中的客戶端服務修改配置如下:
在這裏插入圖片描述
則停止任務兩個註冊服務,最後一個都可以正常註冊服務。

Eureka和Zookeeper對比

Zookeeper在設計的時候遵循的是CP原則,即一致性,Zookeeper會出現這樣一種情況,當master節點因爲網絡故障與其他節點失去聯繫時剩餘節點會重新進行leader選舉,問題在於,選舉leader的時間太長:30~120s,且選舉期間整個Zookeeper集羣是不可用的,這就導致在選舉期間註冊服務處於癱瘓狀態,在雲部署的環境下,因網絡環境使Zookeeper集羣失去master節點是較大概率發生的事情,雖然服務能夠最終恢復,但是漫長的選舉時間導致長期的服務註冊不可用是不能容忍的。
Eureka在設計的時候遵循的是AP原則,即可用性。Eureka各個節點(服務)是平等的, 沒有主從之分,幾個節點down掉不會影響正常工作,剩餘的節點(服務) 依然可以提供註冊與查詢服務,而Eureka的客戶端在向某個Eureka註冊或發現連接失敗,則會自動切換到其他節點,也就是說,只要有一臺Eureka還在,就能註冊可用(保證可用性), 只不過查詢到的信息不是最新的(不保證強一致),除此之外,Eureka還有自我保護機制,如果在15分鐘內超過85%節點都沒有正常心跳,那麼eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現一下情況:

  • Eureka 不再從註冊列表中移除因爲長時間沒有收到心跳而過期的服務。
  • Eureka 仍然能夠接收新服務的註冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點可用)
  • 當網絡穩定後,當前實例新的註冊信息會被同步到其它節點中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章