什么是Eureka? 单机版Eureka如何使用?
Eureka 是什么?
- Eureka 是Spring Cloud的服務治理組件,有三個核心角色: 服務注冊中心、服務提供者、服務消費者。Eureka 主管服務注冊中心。 是Netflix的一個子模塊,也是核心模塊之一。Eureka是一個基于REST的服務,用于定位服務,以實現定位服務,以實現云端中間層服務發現和故障轉移。服務注冊與發現對于微服務架構來說是非常重要的,有了服務發現與注冊,只需要使用服務的標識符,就可以訪問到服務,而不需要修改服務調用的配置文件了,功能類似于dubbo的注冊中心比如Zookeeper。
- Netflix 在設計Eureka 時遵守的就是AP原則(CAP原則又稱CAP定理,指的是在一個分布式系統中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可兼得)
- Eureka 采用了 C-S 的設計架構。Eureka Server 作為服務注冊功能的服務器,它是服務注冊中心。
- 系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server并維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,并執行相關的邏輯。
三大角色
服務提供者
- “服務提供者” 在啟動的時候會通過發送REST請求的方式將自己注冊到EurekaServer 上, 同時帶上了自身服務的一些元數據信息。Eureka Server接收到這個REST請求之后, 將元數據信息存儲在一個雙層結構Map中, 其中第一層的key是服務名, 第二層的key是 具體服務的實例名。(我們可以回想一下之前在實現Ribbon負載均衡的例子中, Eureka信 息面板中一個服務有多個實例的清況, 這些內容就是以這樣的雙層Map形式 存儲的。) 在服務注冊時, 需要確認一下 eureka.cli ent.register-with-eureka=true 參數是否正確, 該值默認為true。 若設置為false將不會 啟動注冊操作。
- 兩個服務提供者分別注冊到了兩個不同的服務注冊中心上, 也就是說, 它們的信息分別被兩個服務注冊中心所維護。 此時, 由于服務注冊中心之間因 互相注冊為服務, 當服務提供者發送注冊請求到一個服務注冊中心時, 它會將該請求轉發 給集群中相連的其他注冊中心, 從而實現注冊中心之間的服務同步 。 通過服務同步,兩個 服務提供者的服務信息就可以通過這兩臺服務注冊中心中的任意一臺獲取到。
- 在注冊完服務之后,服務提供者會維護一個心跳用來持續告訴Eureka Server: "我還活 著 ”, 以防止Eureka Server的 “剔除任務 ” 將該服務實例從服務列表中排除出去,我們稱 該操作為服務續約(Renew)。 eureka.instance.lease-renewal-interval-in-seconds 參數用于定義服 務續約任務的調用間隔時間,默認為30秒。 eureka.instance.lease-expiration-duration-in-seconds參數用于定義服務失效的時間,默認為90秒。
服務消費者
- 獲取服務。 服務注冊中心已經注冊了 一個服務, 并且該服務有兩個實例。 當我們啟動 服務消費者的時候, 它會發送一個REST請求給服務注冊中心,來獲取上面注冊的服務清 單 。 為了性能考慮, Eureka Server會維護一份只讀的服務清單來返回給客戶端,同時該緩 存清單會每隔30秒更新 一次。 獲取服務是服務消費者的基礎,所以必須確保eureka.client.fetch-registry= true參數沒有被修改成false, 該值默認為true。若希望修改緩存清單的 更新時間,可 以通過 eureka.client.registry-fetch-interval-seconds= 30參數進行修改, 該參數默認值為30, 單位為秒。
- 服務調用。服務消費者在 獲取服務清單后,通過服務名可以獲得具體提供服務的實例名和該實例 的元數據信息。 因為有這些服務實例的詳細信息, 所以客戶端可以根據自己的需要決定具 體調用哪個實例,在Ribbon中會默認采用輪詢的方式進行調用,從而實現客戶端的負載均 衡。
- 服務下線。在系統運行過程中必然會面臨關閉或重啟服務的某個實例的情況, 在服務關閉期間, 我們自然不希望客戶端會繼續調用關閉了的實例。 所以在客戶端程序中, 當服務實例進行 正常的關閉操作時, 它會觸發一個服務下線的 REST請求給Eureka Server, 告訴服務注冊 中心:“我要下線了” 。 服務端在接收到請求之后, 將該服務狀態置為下線(DOWN), 并把 該下線事件傳播出去。
服務注冊中心
- 失效剔除。 有些時候, 我們的服務實例并不一定會正常下線, 可能由于內存溢出、 網絡故障等原 因使得服務不能正常工作, 而服務注冊中心并未收到 “服務下線” 的請求。 為了從服務列 表中將這些無法提供服務的實例剔除, Eureka Server在啟動的時候會創建一個定時任務, 默認每隔一段時間(默認為60秒) 將當前清單中超時(默認為90秒)沒有續約的服務剔 除出去。
- 自我保護。Eureka Server 在運行期間,會統計心跳失敗的比例在15分鐘之內是否低于85%, 如果出現低于的情況(在 單機調試的時候很容易滿足, 實際在生產環境上通常是由于網絡不穩定導致), Eureka Server會將當前的實例注冊信息保護起來, 讓這些實例不會過期, 盡可能保護這些注冊信 息。 但是, 在這段保護期間內實例若出現問題, 那么客戶端很容易拿到實際已經不存在的 服務實例, 會出現調用失敗的清況, 所以客戶端必須要有容錯機制, 比如可以使用請求重 試、 斷路器等機制。 由于本地調試很容易觸發注冊中心的保護機制, 這會使得注冊中心維護的服務實例不 那么準確。 所以, 我們在本地進行開發的時候, 可以使用 eureka.server.enable-self-preservation=false 參數來關閉保護機制,以確保注冊中心可以將不可用的實例正確剔除。
Eureka 包含兩個組件:Eureka Server和Eureka Client
-
Eureka Server 提供服務注冊服務
各個節點啟動后,會在EurekaServer 中進行注冊,這樣EurekaServer 中的服務注冊表建輝存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到
-
Eureka Client Java客戶端
Eureka Client 是一個 Java客戶端,用于簡化Eureka Server 的交互,客戶端同時也丠一個內置的使用輪詢(round-robin)負載算法的負載均衡器。在應用啟動后,將會向Eureka Server 發送心跳(默認周期是30s)如果Eureka Server 在多個心跳周期內沒有接受到某個節點的心跳,EurekaServer 將會從服務注冊表中把這個服務節點移除(默認90s)
Eureka 自我保護機制
默認情況下,如果EurekaServer在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer將會注銷該實例(默認90秒)。但是當網絡分區故障發生時,微服務與EurekaServer之間無法正常通信,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該注銷這個微服務。Eureka通過“自我保護模式”來解決這個問題——當EurekaServer節點在短時間內丟失過多客戶端時(可能發生了網絡分區故障),那么這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務注冊表中的信息,不再刪除服務注冊表中的數據(也就是不會注銷任何微服務)。當網絡故障恢復后,該Eureka Server節點會自動退出自我保護模式。
在自我保護模式中,Eureka Server會保護服務注冊表中的信息,不再注銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務注冊信息,也不盲目注銷任何可能健康的服務實例。一句話講解:好死不如賴活著
綜上,自我保護模式是一種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目注銷任何健康的微服務。使用自我保護模式,可以讓Eureka集群更加的健壯、穩定。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保護模式。
某時刻某一個微服務不可用了,eureka不會立刻清理,依舊會對該微服務的信息進行保存
上面主要是關于Eureka的介紹,下面Base之前構建的服務的生產者和消費者來實現單機版的Eureka
Eureka 服務注冊中心模塊
新建模塊: springcloudDemo-Eureka-7001,具體的使用Maven構建模塊的操作方法就不演示了,請查看上面的關聯文章。具體項目結構:
POM文件
<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"><modelVersion>4.0.0</modelVersion><parent><groupId>com.mike.demo</groupId><artifactId>springcloudDemo</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>springcloudDemo-Eureka-7001</artifactId><dependencies><!--eureka-server服務端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId></dependency><!-- 修改后立即生效,熱部署 --><dependency><groupId>org.springframework</groupId><artifactId>springloaded</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency></dependencies> </project>application.yml 配置文件
server: port: 7001eureka:instance:hostname: eureka7001.com #eureka服務端的實例名稱, C:\Windows\System32\drivers\etc 的hosts已經加入映射client:register-with-eureka: false #false表示不向注冊中心注冊自己。fetch-registry: false #false表示自己端就是注冊中心,我的職責就是維護服務實例,并不需要去檢索服務service-url:#單機defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設置與Eureka Server交互的地址查詢服務和注冊服務都需要依賴這個地址。配置Windows hosts文件
打開 C:\Windows\System32\drivers\etc
將域名 eureka7001.com 映射到 127.0.0.1
至于其他操作系統,大家可以百度一下或谷歌,由于之后會有集群所以為了方便設置了域名。
Eureka 主啟動類
package com.mike.demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication @EnableEurekaServer//EurekaServer服務器端啟動類,接受其它微服務注冊進來 public class EurekaServer7001_App {public static void main(String[] args){SpringApplication.run(EurekaServer7001_App.class, args);} }服務注冊中心測試
啟動 Eureka 模塊
http://eureka7001.com:7001/
這里可以看到,沒有任何服務注冊進來。
修改服務提供者
服務提供者: springcloudDemo-provider-dept-8001,這個模塊在之前我們已經構建完成。請查看文章開口的文章列表。
POM
pom文件添加Eureka 的依賴
<!-- 將微服務provider側注冊進eureka --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><!-- 監控插件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>父項目POM文件修改
父項目(springcloudDemo)
在POM文件中加入:
上面的修改主要是為了使 服務的提供者 設置的服務信息生效即下方的application.yml 修改中的內容:
info:app.name: atguigu-springcloudDemocompany.name: www.atguigu.combuild.artifactId: $project.artifactId$build.version: $project.version$修改 application.yml
server:port: 8001mybatis:config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑type-aliases-package: com.mike.demo.entities # 所有Entity別名類所在包mapper-locations:- classpath:mybatis/mapper/**/*.xml # mapper映射文件spring:application:name: springcloudDemo-dept datasource:type: com.alibaba.druid.pool.DruidDataSource # 當前數據源操作類型driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包url: jdbc:mysql://XXXXXXXXXX:3306/cloudDB01 # 數據庫名稱username: rootpassword: XXXXdbcp2:min-idle: 5 # 數據庫連接池的最小維持連接數initial-size: 5 # 初始化連接數max-total: 5 # 最大連接數max-wait-millis: 200 # 等待連接獲取的最大超時時間eureka:client: #客戶端注冊進eureka服務列表內service-url: #單機版defaultZone: http://localhost:7001/eurekainstance: # 將服務名稱修改 (頁面中顯示服務名稱 原: localhost:springcloudDemo-dept:8001 修改為springcloudDemo-dept8001)instance-id: springcloudDemo-dept8001prefer-ip-address: true info:app.name: atguigu-springcloudDemocompany.name: www.atguigu.combuild.artifactId: $project.artifactId$build.version: $project.version$啟動類添加Eureka的Enable
@EnableEurekaClient //本服務啟動后會自動注冊進eureka服務中
修改完畢,測試
查看服務是否注冊進已經開啟的Eureka服務器,首先啟動Eureka服務器再啟動服務的提供者(先有聯通運營商后有我們這些聯通用戶并聯網)
查看截圖:
紅框的查看已經顯示了有一個服務注冊進入到了Eureka服務器中,上面的紅色報錯,是因為Eureka自我保護機制導致,長時間沒有服務注冊。
下面重啟所有的服務,查看錯誤是否消除
- 由上圖可以看到,重啟Eureka和服務提供者后,Eureka由于自我保護機制出現的錯誤消失了
- SPRINGCLOUDDEMO-DEPT 是由 application.yml 配置文件中定義的
- springcloudDemo-dept8001 是由 application.yml 配置文件中定義的
- 點擊 springcloudDemo-dept8001 可以查看該服務節點的詳細信息,這里的詳細信息也是在application.yml 中配置的
- 測試服務提供者
Eureka 服務發現
– 對于注冊進eureka里面的微服務,可以通過服務發現來獲得該服務的信息
服務提供者修改Controller
import org.springframework.cloud.client.discovery.DiscoveryClient;@Autowiredprivate DiscoveryClient client;// Eureka 服務發現測試 @RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)public Object discovery(){List<String> list = client.getServices();System.out.println("**********" + list);List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");for (ServiceInstance element : srvList) {System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"+ element.getUri());}return this.client;}啟動類添加注解 @EnableDiscoveryClient
測試
重啟Eureka 和 provider
輸入: http://eureka7001.com:8001/dept/discovery
自此單節點的Eureka 如何部署并使用已經完成了。
總結
以上是生活随笔為你收集整理的什么是Eureka? 单机版Eureka如何使用?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英语笔录(1)
- 下一篇: 程序员法律考试(5)-民法(2)