SpringCloud?Eureka應(yīng)用全面介紹
Eureka
什么是服務(wù)治理
為什么需要服務(wù)治理?
服務(wù)治理是主要針對(duì)分布式服務(wù)框架的微服務(wù),處理服務(wù)調(diào)用之間的關(guān)系、服務(wù)發(fā)布和發(fā)現(xiàn)、故障監(jiān)控與處理,服務(wù)的參數(shù)配置、服務(wù)降級(jí)和熔斷、服務(wù)使用率監(jiān)控等。
需要服務(wù)治理的原因:
- 過(guò)多的服務(wù) URL 配置困難
- 負(fù)載均衡分配節(jié)點(diǎn)壓力過(guò)大的情況下,需要部署集群
- 服務(wù)依賴混亂,啟動(dòng)順序不清晰
- 過(guò)多服務(wù),導(dǎo)致性能指標(biāo)分析難度較大,需要監(jiān)控
- 故障定位與排查難度較大
什么是服務(wù)注冊(cè)與發(fā)現(xiàn)
服務(wù)注冊(cè)主要針對(duì)服務(wù)提供者,服務(wù)啟動(dòng)后需要將本身以別名的方式注冊(cè)到注冊(cè)中心上;而服務(wù)發(fā)現(xiàn)主要是針對(duì)消費(fèi)者(服務(wù)使用者),它在調(diào)用服務(wù)的時(shí)候需要通過(guò)別名去注冊(cè)中心獲取到相應(yīng)的服務(wù),然后再實(shí)現(xiàn)本地RPC調(diào)用遠(yuǎn)程RPC的功能。
Eureka的兩大組件
Eureka Server: 提供注冊(cè)服務(wù),各節(jié)點(diǎn)啟動(dòng)時(shí),會(huì)在EurekaServer中進(jìn)行注冊(cè),各服務(wù)的節(jié)點(diǎn)信息會(huì)儲(chǔ)存在EurekaServer中的服務(wù)注冊(cè)表中。
Eureka Client: 其本質(zhì)是一個(gè)Java客戶端,用于簡(jiǎn)化Eureka Server的交互,客戶端同時(shí)也具備一個(gè)內(nèi)置的使用負(fù)載算法的負(fù)載均衡器在啟動(dòng)應(yīng)用后將會(huì)向Eureka Server發(fā)送心跳(默認(rèn)周期30s),如果EurekaServer在多個(gè)心跳周期內(nèi)沒(méi)有接收到某節(jié)點(diǎn)的心跳,將會(huì)把該節(jié)點(diǎn)從服務(wù)注冊(cè)表上移除(默認(rèn)周期90s)
Eureka的使用
Eureka服務(wù)端server的創(chuàng)建
首先是創(chuàng)建一個(gè)子模塊作為eureka的服務(wù)器模塊,主要與其他的子模塊有以下三處不同:
一、導(dǎo)入eureka服務(wù)端的依賴
<!-- 服務(wù)注冊(cè)中心的服務(wù)端 eureka-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
二、配置文件配置eureka相關(guān)
# eureka的單機(jī)版配置
eureka:
instance:
hostname: localhost #eureka服務(wù)端的實(shí)例名字
client:
register-with-eureka: false #表示不向注冊(cè)中心注冊(cè)自己
fetch-registry: false #表示自己就是注冊(cè)中心,職責(zé)是維護(hù)服務(wù)實(shí)例,并不需要去檢索服務(wù)
service-url:
#設(shè)置與eureka server交互的地址查詢服務(wù)和注冊(cè)服務(wù)都需要依賴這個(gè)地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
三、主程序類上使用注解開(kāi)啟服務(wù)器
@SpringBootApplication @EnableEurekaServer public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class, args); } }
Eureka客戶端client的創(chuàng)建
之前創(chuàng)建的支付子模塊8001就可以標(biāo)記為Eureka的客戶端,我們需要做的和Eureka服務(wù)端的三步一樣:
一、導(dǎo)入eureka客戶端的依賴
<!--Eureka客戶端依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
二、配置文件配置eureka相關(guān)
eureka:
client:
register-with-eureka: true #是否向注冊(cè)中心注冊(cè)自己
fetchRegistry: true #是否從注冊(cè)中心抓取已有的注冊(cè)信息 默認(rèn)true
service-url:
defaultZone: http://localhost:7001/eureka #服務(wù)端的地址
三、主程序類使用注解開(kāi)啟客戶端
@SpringBootApplication @EnableEurekaClient public class Payment8001Application { public static void main(String[] args) { SpringApplication.run(Payment8001Application.class, args); } }
紅框顯示當(dāng)前名稱為CLOUD-PAYMENT-SERVICE的服務(wù)狀態(tài)為UP,也就是說(shuō)這個(gè)模塊已經(jīng)被注冊(cè)進(jìn)了eureka服務(wù)
目前為止,我們的eureka服務(wù)端上就只有一個(gè)支付模塊作為服務(wù)的提供者注冊(cè)進(jìn)eureka服務(wù)器,并沒(méi)有服務(wù)的調(diào)用者,于是乎我們可以將80端口的消費(fèi)者模塊通過(guò)以上三步,將其作為eureka客戶端注冊(cè)進(jìn)eureka服務(wù)器,讓其實(shí)現(xiàn)服務(wù)的調(diào)用
集群搭建
Eureka服務(wù)端的集群搭建
想必集群的好處這里就不需要再進(jìn)行贅述了,單體的服務(wù)器一旦出現(xiàn)故障整個(gè)項(xiàng)目就搞崩了,如果是集群就不一樣了,一個(gè)故障其他頂上,服務(wù)之間可以實(shí)現(xiàn)互相注冊(cè)相互守望
現(xiàn)在我們就創(chuàng)建一個(gè)新的服務(wù)端子模塊命名7002,作為集群中的另一個(gè)模塊使用。那么,如何實(shí)現(xiàn)互相注冊(cè)相互守望呢?答案就是:分別在配置文件中配置,使集群中的服務(wù)都能互相發(fā)現(xiàn),其中最重要的就是defaultZone字段的對(duì)應(yīng)值
server:
port: 7001# eureka的單機(jī)版配置
eureka:
instance:
hostname: eureka7001.com #eureka服務(wù)端的實(shí)例名字,這里以localhost代替
client:
register-with-eureka: false #表示不向注冊(cè)中心注冊(cè)自己
fetch-registry: false #表示自己就是注冊(cè)中心,職責(zé)是維護(hù)服務(wù)實(shí)例,并不需要去檢索服務(wù)
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 單機(jī)版,指向的是自己
# 集群版,指向集群中的其他服務(wù)
defaultZone: http://eureka7002.com:7002/eureka/,
http://eureka7003.com:7003/eureka/
server:
port: 7002# eureka的單機(jī)版配置
eureka:
instance:
hostname: eureka7002.com #eureka服務(wù)端的實(shí)例名字,這里以localhost代替
client:
register-with-eureka: false #表示不向注冊(cè)中心注冊(cè)自己
fetch-registry: false #表示自己就是注冊(cè)中心,職責(zé)是維護(hù)服務(wù)實(shí)例,并不需要去檢索服務(wù)
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 單機(jī)版,指向的是自己
# 集群版,指向集群中的其他服務(wù)
defaultZone: http://eureka7001.com:7001/eureka/,
http://eureka7003.com:7003/eureka/
server:
port: 7003# eureka的單機(jī)版配置
eureka:
instance:
hostname: localhost # eureka服務(wù)端的實(shí)例名字,這里以localhost代替
client:
register-with-eureka: false #表示不向注冊(cè)中心注冊(cè)自己
fetch-registry: false #表示自己就是注冊(cè)中心,職責(zé)是維護(hù)服務(wù)實(shí)例,并不需要去檢索服務(wù)
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 單機(jī)版,指向的是自己
# 集群版,指向集群中的其他服務(wù)
defaultZone: http://eureka7001.com:7001/eureka/,
http://eureka7002.com:7002/eureka/
集群搭建完畢之后,服務(wù)也要向集群中的所有模塊進(jìn)行注冊(cè),那么就需要使用配置文件了,這里以服務(wù)調(diào)用者80端口為例
server:
port: 80spring:
application:
name: cloud-order-serviceeureka:
client:
register-with-eureka: true #是否向注冊(cè)中心注冊(cè)自己
fetchRegistry: true #是否從注冊(cè)中心抓取已有的注冊(cè)信息 默認(rèn)true
service-url:
# defaultZone: http://localhost:7001/eureka #服務(wù)端的地址#服務(wù)端的地址,服務(wù)端為集群版,向所有的模塊都注冊(cè)
defaultZone: http://localhost:7001/eureka,
http://localhost:7002/eureka,
http://localhost:7003/eureka
Eureka客戶端的集群搭建
從8001模塊copy一個(gè)為8002,作為客戶端集群的另一個(gè)模塊,同樣使用配置文件,將其也注冊(cè)進(jìn)服務(wù)端集群。此時(shí)就可以使用服務(wù)調(diào)用者80進(jìn)行調(diào)用了,但是80的controller是直接寫死的域名和端口,于是需要將域名端口改為微服務(wù)的名稱,然后在服務(wù)調(diào)用者80模塊開(kāi)啟負(fù)載均衡讓請(qǐng)求合理的分配到服務(wù)集群的每一個(gè)模塊
將原先的指定域名+端口改為指定服務(wù)
配置中開(kāi)啟負(fù)載均衡
這樣集群就部署好了,可以實(shí)現(xiàn)服務(wù)調(diào)用對(duì)8001和8002的輪詢
微服務(wù)模塊的相關(guān)配置
配置服務(wù)的名稱
eureka:
instance:
instance-id: payment8001
訪問(wèn)路徑顯示IP地址
eureka:
instance:
prefer-ip-address: true
服務(wù)發(fā)現(xiàn)
所謂的服務(wù)發(fā)現(xiàn)就是對(duì)于已經(jīng)注冊(cè)進(jìn)eureka里的微服務(wù),可以通過(guò)這個(gè)方式來(lái)獲得該服務(wù)的相關(guān)信息,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)功能分三步走:
一、對(duì)象注入
@Resource private DiscoveryClient discoveryClient;
二、調(diào)用api獲取服務(wù)信息
@GetMapping(value = "/discovery") public Object discovery() { List<String> services = discoveryClient.getServices(); for (String service : services) { log.info("***********service: " + service); } List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); for (ServiceInstance instance : instances) { log.info(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri()); } return this.discoveryClient; }
三、主程序入口注解開(kāi)啟發(fā)現(xiàn)功能
@EnableDiscoveryClient
這樣即可打印服務(wù)的相關(guān)信息
自我保護(hù)機(jī)制
什么是自我保護(hù)機(jī)制
EurekaServer會(huì)檢查最近15分鐘內(nèi)所有EurekaClient正常心跳占比,如果低于85%就會(huì)觸發(fā)自我保護(hù)機(jī)制,此時(shí)Eureka暫時(shí)把這些失效的服務(wù)保護(hù)起來(lái),不會(huì)立即將其剔除。Eureka在啟動(dòng)完成后,每隔60秒會(huì)檢查一次服務(wù)健康狀態(tài),如果這些暫時(shí)失效的服務(wù)過(guò)一段時(shí)間后(默認(rèn)90秒)還是沒(méi)有恢復(fù),就會(huì)把這些服務(wù)剔除。反之這個(gè)服務(wù)就不會(huì)因?yàn)榫W(wǎng)絡(luò)的延時(shí)、卡頓、擁擠等問(wèn)題而被錯(cuò)誤刪除。
總而言之,自我保護(hù)機(jī)制就是說(shuō)某一時(shí)刻微服務(wù)不可用時(shí),Eureka不會(huì)立即將其剔除,而是在一段時(shí)間內(nèi)等待其正常發(fā)送心跳。這屬于CAP原則的AP分支,主要保證了可用性和分區(qū)容錯(cuò)性
如何禁用自我保護(hù)機(jī)制
服務(wù)端使用配置文件關(guān)閉eureka的自我保護(hù)機(jī)制
eureka:
server:
# 關(guān)閉自我保護(hù)機(jī)制,保證不可用服務(wù)被及時(shí)踢除
enable-self-preservation: false
#
eviction-interval-timer-in-ms: 2000
客戶端使用配置文件設(shè)置心跳相關(guān)配置
eureka:
instance:
# Eureka客戶端向服務(wù)端發(fā)送心跳的時(shí)間間隔,單位為秒(默認(rèn)是30秒)
lease-renewal-interval-in-seconds: 1
# Eureka服務(wù)端在收到最后一次心跳后等待時(shí)間上限,單位為秒(默認(rèn)是90秒),超時(shí)將剔除服務(wù)
lease-expiration-duration-in-seconds: 2
到此這篇關(guān)于SpringCloud Eureka應(yīng)用全面介紹的文章就介紹到這了,更多相關(guān)SpringCloud Eureka內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)駝峰和下劃線互相轉(zhuǎn)換的示例代碼
Java對(duì)各種變量、方法和類等要素命名時(shí)使用的字符序列稱為標(biāo)識(shí)符,凡是自己可以起名字的地方都叫標(biāo)識(shí)符。本文為大家分享了Java中如何實(shí)現(xiàn)駝峰命名與下劃線命名的互轉(zhuǎn),感興趣的可以了解一下2022-05-05Java并發(fā)系列之AbstractQueuedSynchronizer源碼分析(共享模式)
這篇文章主要為大家詳細(xì)介紹了Java并發(fā)系列之AbstractQueuedSynchronizer源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02SpringBoot中實(shí)現(xiàn)@Scheduled動(dòng)態(tài)定時(shí)任務(wù)
SpringBoot中的@Scheduled注解為定時(shí)任務(wù)提供了一種很簡(jiǎn)單的實(shí)現(xiàn),本文主要介紹了SpringBoot中實(shí)現(xiàn)@Scheduled動(dòng)態(tài)定時(shí)任務(wù),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01Java為什么匿名內(nèi)部類參數(shù)引用需要用final進(jìn)行修飾?
今天小編就為大家分享一篇關(guān)于Java為什么匿名內(nèi)部類參數(shù)引用需要用final進(jìn)行修飾?,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04