【Java进阶】Eureka讲解与应用
Eureka[ju?ri?k?]
簡介
Eureka是Netflix服務發現的服務端與客戶端,Eureka提供服務注冊以及服務發現的能力,當是Eureka Server時(注冊中心),所有的客戶端會向其注冊,當是Eureka Client時,可以從注冊中心獲取對應的服務信息,或者是向Eureka Server將自己作為實例注冊進去,每個Eureka不僅僅是一個服務端同時還是一個客戶端。
注冊中心
當Eureka想要成為注冊中心時,必須將注冊中心的服務地址指向自己,同時禁用服務檢索的功能。Eureka是一個高可用的組件,它沒有后端緩存,每一個實例注冊之后需要向注冊中心發送心跳來檢測服務的可用性,注冊中心不處理請求的轉發,只是記錄每個實例注冊進來的信息。
項目搭建
- 導入依賴
- 編寫配置文件
- 開啟這個功能 @EnableXXXXXX
- 配置類
Eureka服務
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>cn.com.codingce</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-eureka-7001</artifactId><dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies> </project>EurekaServer
package cn.com.codingce;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer //EnableEurekaServer 服務端啟動類 public class EurekaServer {public static void main(String[] args) {SpringApplication.run(EurekaServer.class, args);} }application.yml
server:port: 7001# Eureka配置 eureka:instance:hostname: localhost #Eureka服務端實例的名字client:register-with-eureka: false # 表示是否向eureka注冊中心注冊自己fetch-registry: false # 表示如果 false 則表示自己為注冊中心service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/Eureka 的自我保護模式詳解
訪問Eureka主頁時,如果看到這樣一段大紅色的句子:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
(那么就表明著Eureka的 自我保護模式(self-preservation mode) 被啟動了,當 Eureka Server 節點在短時間內丟失了過多實例的連接時(比如網絡故障或頻繁的啟動關閉客戶端),那么這個節點就會進入自我保護模式,一旦進入到該模式,Eureka server 就會保護服務注冊表中的信息,不再刪除服務注冊表中的數據(即不會注銷任何微服務),當網絡故障恢復后,該 Ereaka Server 節點就會自動退出自我保護模式)
-
在自我保護模式中, EurekaServe 會保護注冊表中的信息, 不再注銷任何服務實例. 當他重新收到心跳數重新恢復到閾值以上時, 該EurekaServe節點就會自動推出自我保護模式. 它的哲學就是寧可保存錯誤的服務注冊信息, 也不盲目注銷任何可能健康的實例, 一句話:好死不如賴活著
-
綜上, 自我保護模式中, 自我保護模式是一種應對網絡異常安全保護措施, 它的架構哲學是寧可同時保留所有微服務(健康的服務和不健康的服務都會保留), 也不盲目注銷任何健康的服務. 使用自我保護模式, 可以讓Eureka集群更加健壯和穩定.
在SpringCloud中, 可以使用eureka.serve.enable-self-preservation = false 禁用自我保護模式
[不推薦關閉自我保護機制]
默認情況下,如果 Ereaka Server 在一段時間內沒有接受到某個微服務示例的心跳,便會注銷該實例(默認90秒),而一旦進入自我保護模式,那么即使你關閉了指定實例,仍然會發現該 Ereaka Server 的注冊實例中會存在被關閉的實例信息,如果你對該實例做了負載均衡,那么僅關閉了其中一個實例,則通過網關調用接口api時很可能會發生如下異常:
{ "timestamp": 1507707671780, "status": 500, "error": "Internal Server Error", "exception": "com.netflix.zuul.exception.ZuulException", "message": "GENERAL" }解決這種情況的方法主要有幾種方式:
-
等待 Eureka Server 自動恢復
正常的情況下,等待網絡恢復(或者沒有頻繁的啟動與關閉實例)后,等待一段時間 Eureka Server 會自動關閉自我保護模式,但是如果它遲遲沒有關閉該模式,那么便可以嘗試手動關閉,如下。 -
重啟 Eureka Server
通常而言,PRD 環境建議對 Eureka Server 做負載均衡,這樣在依次關閉并開啟 Eureka Server 后,無效的實例會被清除,并且不會對正常的使用照成影響。 -
關閉 Eureka 的自我保護模式
在yml配置文件中新增如下配置:
對比Zookeeper
回顧CAP原則
RDBMS(Mysql、Oracle、sqlServer) >ACID
NoSQL(redis、 mongdb)>CAP
ACID是什么
- A(Atomicity)原子性:事務里面的所有操作,要么全部做完,要么都不做,只要有一個失敗,整個事務都失敗,需要回滾
- C(Consistency)一致性:以轉賬案例為例,假設有五個賬戶,每個賬戶余額是100元,那么五個賬戶總額是500元,如果在這個5個賬戶之間同時發生多個轉賬,無論并發多少個,比如在A與B賬戶之間轉賬5元,在C與D賬戶之間轉賬10元,在B與E之間轉賬15元,五個賬戶總額也應該還是500元,這就是保護性和不變性
- I(Isolation)隔離性:并發的事務之間互不影響
- D(Durability)持久性:事務一旦提交,數據將永久保存在數據庫上
CAP是什么
- C(Consistency)強一致性
- A(Availability)可用性
- P(Partition tolerance) 分區容錯性
CAP的三進二 CA AP CP
CAP理論核心
- 一個分布式系統不可能同時很好的滿足一致性、可用性和分區容錯性三個要求
- 根據CAP原理, 將NOSQL數據庫分成了滿足CA原則, 滿足CP原則滿足AP原則三大類
- CA:單點集群, 滿足一致性, 可用性的系統, 通常可擴展性差
- CP: 滿足一致性, 分區容錯性的系統, 通常性能不是特別高
- AP:滿足可用性,分區容錯性的系統,通常可能對一致性要求低一點
作為服務注冊中心, Eureka比Zookeeper好在哪里
著名的CAP理論指出, 一個分布式系統不可能同時滿足C(一致性)A(可用性)P(容錯性)
由于分區容錯性P在分布式系統中是必須要保證的, 因此我們只能在A和C之前進行權衡
- Zookeeper保證的是CP
- Eureka保證的是AP
Zookeeper保證的是CP
當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的信息,但不能就收服務直接 down 掉不可用。也就是說服務注冊的可用性要高于一致性
當時 zk 會出現這么一個情況,當 mastr 節點因網絡故障和其他節點失去聯系時,剩余節點會重新進行選舉。問題在于,選舉時間比較長,30s~120s,且選舉期間,整個 zk 是不可用的。這就導致了在選舉期間,注冊服務的癱瘓。在云部署的環境下,因網絡問題使 zk 集群時區 master 節點是交大概率會發生的事情,雖然服務能夠最終恢復,但是漫長的選舉時間導致的注冊服務長期不可用是不能容忍的。
Eureka保證的是AP
Eureka 明白這一點,因此在設計時,就優先保證可用性. Eureka 各個節點是平等的 ,幾個節點掛掉不會影響正常工作,只要有一臺 Eureka 存在,就可以保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka 還有一種自我保護機制,如果在 15 分鐘內超過 85% 的節點沒有正常的心跳,那么 Eureka 就會認為客戶端與注冊中心出現了故障,此時會出現以下幾種情況:
- Eureka 不再從注冊列表中移出因長時間沒收到心跳而應該過期的服務
- Eureka 仍然能夠接受新服務的注冊和查詢要求,但是不會被同步到其他節點上(即保證當前節點依然可用)
- 當網絡穩定時,當前實例新的注冊信息會被同步到其他節點中
結論
Eureka 可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像 zookeeper 那樣使整個注冊服務癱瘓
服務注冊與發現集群搭建
springcloud-eureka-7002
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>cn.com.codingce</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-eureka-7002</artifactId><dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies> </project>application.yml
server:port: 7002# Eureka配置 eureka:instance:hostname: eureka7002.com #Eureka服務端實例的名字client:register-with-eureka: false # 表示是否向eureka注冊中心注冊自己fetch-registry: false # 表示如果 false 則表示自己為注冊中心service-url:defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7003.com:7003/eureka/啟動類
package cn.com.codingce;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer //EnableEurekaServer 服務端啟動類 public class EurekaServer_7003 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7003.class, args);} }springcloud-eureka-7003
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>cn.com.codingce</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-eureka-7003</artifactId><dependencies><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><version>1.4.6.RELEASE</version></dependency><!--熱部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies> </project>application.yml
server:port: 7003# Eureka配置 server:port: 7003# Eureka配置 eureka:instance:hostname: eureka7003.com #Eureka服務端實例的名字client:register-with-eureka: false # 表示是否向eureka注冊中心注冊自己fetch-registry: false # 表示如果 false 則表示自己為注冊中心service-url:defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/啟動類
package cn.com.codingce;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer //EnableEurekaServer 服務端啟動類 public class EurekaServer_7003 {public static void main(String[] args) {SpringApplication.run(EurekaServer_7003.class, args);} }總結
以上是生活随笔為你收集整理的【Java进阶】Eureka讲解与应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hexo创建导航页面
- 下一篇: 【Java进阶】Ribbon讲解实现案例