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