Spring-Cloud-Netflix-Eureka註冊中心
目錄
- 概述
- Netflix-Eureka與SpringCloud的關係
- Eureka原理
- CAP定理(瞭解)
(Spring-Cloud-Netflix-Eureka註冊中心)
概述
- eureka是Netflix的子模組之一,也是一個核心的模組
- eureka裡有2個元件:
一個是EurekaServer(一個獨立的專案) 這個是用於定位服務以實現中間層伺服器的負載平衡和故障轉移
一個便是EurekaClient(我們的微服務) 它是用於與Server互動的,可以使得互動變得非常簡單:只需要通過服務識別符號即可拿到服務 - Eureka負責管理、記錄服務提供者的資訊
- 服務呼叫者無需自己尋找服務,而是把自己的需求告訴Eureka,然後Eureka會把符合你需求的服務告訴你。
- 類似家政中心,物業
Netflix-Eureka與SpringCloud的關係
Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模組來實現服務註冊和發現
Eureka原理
- Eureka:就是服務註冊中心(可以是一個叢集),對外暴露自己的地址
- 提供者:啟動後向Eureka註冊自己資訊(地址,提供什麼服務)
- 消費者:向Eureka訂閱服務,Eureka會將對應服務的所有提供者地址列表傳送給消費者,並且定期更新
心跳(續約):提供者定期通過http方式向Eureka重新整理自己的狀態,會監聽有沒有定期更新,如果長時間沒有心跳,就會自動把該服務移除
Eureka使用
- 在之前工程中新增一個子模組名稱為Eureka3000
在總父工程新增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>
- 在Eureka3000的子模組中新增依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
- 在resources當中建立配置檔案application.yml
server:
port: 3000
eureka:
server:
enable-self-preservation: false #關閉自我保護機制
eviction-interval-timer-in-ms: 4000 #設定清理間隔(單位:毫秒 預設是60*1000)
instance:
hostname: localhost
- 建立啟動類,並在啟動器上新增EnableEurekaServer註解
@SpringBootApplication
@EnableEurekaServer
public class Eureka3000App {
public static void main(String[] args) {
SpringApplication.run(Eureka3000App.class, args);
}
}
- 直接啟動會報錯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
執行後,在瀏覽器位址列直接訪問http://localhost:3000/
發現啟動後,還沒有服務進行註冊。服務註冊:
在user工程中新增eureka客戶端相關依賴
<!--Eureka的客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在啟動器上添加註解@EnableEurekaClient
@EnableEurekaClient
- 建立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
- 註冊goods,和上面步驟一樣,注意改一下的地方
啟動Eureka3000,user,goods註冊到註冊中心
可以看到已經註冊成功常用配置:
服務註冊
服務提供者在啟動時,會檢測配置屬性中的:eureka.client.register-with-erueka=true引數是否正確,
事實上預設就是true。如果值確實為true,則會向EurekaServer發起一個Rest請求
獲取服務列表
當服務消費者啟動是,會檢測eureka.client.fetch-registry=true引數的值,如果為true, 則會從Eureka
Server服務的列表只讀備份,然後快取在本地。並且每隔30秒會重新獲取並更新資料。
eureka.client.registry-fetch-interval-seconds: 5 生產環境中,我們不需要修改這個值。服務續約
eureka:
instance:
lease-expiration-duration-in-seconds: 90 :服務續約(renew)的間隔,預設為30秒
lease-renewal-interval-in-seconds: 30 :服務失效時間,預設值90秒
在註冊服務完成以後,服務提供者會維持一個心跳
也就是說,預設情況下每個30秒服務會向註冊中心傳送一次心跳,證明自己還活著。如果超過90秒沒有傳送心跳
EurekaServer就會認為該服務宕機,會從服務列表中移除,這兩個值在生產環境不要修改,預設即可。
失效剔除
有些時候,我們的服務提供方並不一定會正常下線,可能因為記憶體溢位、網路故障等原因導致服務無法正常工作 Eureka
Server需要將這樣的服務剔除出服務列表。因此它會開啟一個定時任務,每隔60秒對所有失效的服務(超過90秒未響應)進行剔除
可以通過eureka.server.eviction-interval-timer-in-ms引數對其進行修改,單位是毫秒自我保護機制
當把一個服務停掉後, 並不會立馬從服務列表當中移除,預設是90秒清除一次
有可以註冊中心和微服務之間出現了網路波動,網路不好,沒有收到心跳,有可能是網路不好,但是微服務還在,所以它不會立馬把服務給移除
當15分鐘內85%的心跳都沒有正常心跳,那麼eureka認為客戶端與註冊中心出現了網路問題,此時會出現以下情況:
1.Eureka不再從註冊列表中移除因為長時間沒有收到的心跳而過期的服務
2.Eureka仍然能夠接收服務的註冊和查詢請求,但是不會被同步到其它節點上
3.當網路穩定後,當前例項新註冊的資訊會被同步到其它節點上
CAP定理(瞭解)
- 什麼是CAP定理
CAP定理又稱CAP原則, 指的是在一個分散式系統中,Consistency(一致性)、
Availability(可用性)、Partition tolerance(分割槽容錯性), 最多隻能同時三個特性中的兩個,三者不可兼得
Consistency (一致性)
“all nodes see the same data at the same time”,
即更新操作成功並返回客戶端後,所有節點在同一時間的資料完全一致,這就是分散式的一致性。Availability(可用性)
可用性指“Reads and writes always succeed” 即服務一直可用,而且是正常響應時間。
好的可用性主要是指系統能夠很好的為使用者服務,不出現使用者操作失敗或者訪問超時等使用者體驗不好的情況Partition tolerance(分割槽容錯性)
大多數分散式系統都分佈在多個子網路。每個子網路就叫做一個區
分割槽容錯的意思是,區間通訊可能失敗。比如,一臺伺服器放在本地,另一臺伺服器放在外地(可能是外省,甚至是外國),這就是兩個區,它們之間可能無法通訊
兩臺跨區的伺服器。Server1 向 Server2 傳送一條訊息,Server2 可能無法收到。系統設計的時候,必須考慮到這種情況.
一般來說,分割槽容錯無法避免,因此可以認為 CAP 的 P 總是成立
即分散式系統在遇到某節點或網路分割槽故障的時候,仍然能夠對外提供滿足一致性或可用性的服務。
分割槽容錯性要求能夠使應用雖然是一個分散式系統,而看上去卻好像是在一個可以運轉正常的整體。Consistency 和 Availability 的矛盾
如果保證 Server2 的一致性,那麼 Server1 必須在寫操作時,鎖定 Server2
的讀操作和寫操作。只有資料同步後,才能重新開放讀寫。鎖定期間,Server2 不能讀寫,沒有可用性 如果保證 Server2的可用性,那麼勢必不能鎖定 Server2,所以一致性不成立取捨策略
CAP三個特性只能滿足其中兩個,那麼取捨的策略就共有三種:
1.CA without P:如果不要求P(不允許分割槽),則C(強一致性)和A(可用性)是可以保證的。
但放棄P的同時也就意味著放棄了系統的擴充套件性,也就是分散式節點受限,沒辦法部署子節點, 這是違背分散式系統設計的初衷的。
2.CP without A:
如果不要求A(可用),相當於每個請求都需要在伺服器之間保持強一致,而P(分割槽)會導致同步時間無限延長
(也就是等待資料同步完才能正常訪問服務)
一旦發生網路故障或者訊息丟失等情況,就要犧牲使用者的體驗,等待所有資料全部一致了之後再讓使用者訪問系統。
3.AP wihtout C:
要高可用並允許分割槽,則需放棄一致性。 一旦分割槽發生,節點之間可能會失去聯絡,為了高可用,每個節點只能用本地資料提供服務
而這樣會導致全域性資料的不一致性。
搶購商品時,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在
A(可用性)方面保證系統可以正常的服務,然後在資料的一致性方面做了些犧牲,雖然多少會影響一些使用者體驗,但也不至於造成使用者購物流程的嚴重阻塞。沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的才是最好的