文章目錄
My Name is YangYang
Eureka簡介
在微服務架構中往往會有一個註冊中心,每個微服務都會向註冊中心去註冊自己的地址及端口信息,註冊中心維護着服務名稱與服務實例的對應關係。每個微服務都會定時從註冊中心獲取服務列表,同時彙報自己的運行情況,這樣當有的服務需要調用其他服務時,就可以從自己獲取到的服務列表中獲取實例地址進行調用,Eureka實現了這套服務註冊與發現機制。
搭建Eureka註冊中心
使用IDEA來創建SpringCloud應用
Eureka分爲註冊和發現,所以需要創建Server模塊和Client模塊,簡單些講實際項目中Eureka作爲註冊Server模塊,其他子服務屬於Client模塊。
- 創建一個eureka-server模塊,並使用Spring Initializer初始化一個SpringBoot項目
- 填寫應用信息
- 選擇你需要的SpringCloud組件進行創建
- 添加Pom.xml依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 在啓動類上添加@EnableEurekaServer註解來啓用Euerka註冊中心功能
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
- 在配置文件application.yml中添加Eureka註冊中心的配置
server:
port: 8001 #指定運行端口
spring:
application:
name: eureka-server #指定服務名稱
eureka:
instance:
hostname: localhost #指定主機地址
client:
fetch-registry: false #指定是否要從註冊中心獲取服務(註冊中心不需要開啓)
register-with-eureka: false #指定是否要註冊到註冊中心(註冊中心不需要開啓)
server:
enable-self-preservation: false #關閉保護模式
使用IDEA的Run Dashboard來運行SpringCloud應用
- 打開Run Dashboard,默認情況下,當IDEA檢查到你的項目中有SpringBoot應用時,會提示你開啓,如果你沒開啓,可以用以下方法開啓。
- 運行SpringCloud應用
- 運行完成後訪問地址 http://localhost:8001/ 可以看到Eureka註冊中心的界面
搭建Eureka客戶端
- 新建一個eureka-client模塊,並在pom.xml中添加如下依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 在啓動類上添加@EnableDiscoveryClient註解表明是一個Eureka客戶端
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
- 在配置文件application.yml中添加Eureka客戶端的配置
server:
port: 8101 #運行端口號
spring:
application:
name: eureka-client #服務名稱
eureka:
client:
register-with-eureka: true #註冊到Eureka的註冊中心
fetch-registry: true #獲取註冊實例列表
service-url:
defaultZone: http://localhost:8001/eureka/ #配置註冊中心地址
- 運行Eureka-Client
- 查看註冊中心http://localhost:8001/ 發現Eureka客戶端已經成功註冊
Eureka原理圖
-
庫存服務註冊原理圖
-
eureka底層實現是使用concurrentHashMap,圖中爲eureka的實現原理可以很清楚的理解,其中有個多級緩存,服務每隔30s發送一個心跳。
-
註冊到服務註冊中心,接着立馬同步到readwith緩存中,接着30s同步到readonly緩存中,然後服務每隔30s拉取註冊表即可調用註冊中的服務。
-
服務下線是在eureka中有個每隔60s的定時檢查,然後從readwith中剔除,30s後再從readonly中剔除,再會去被拉取。
-
從中可以看出時間還是比較長的,當在生產環境中還是要優化一下的,服務的發現還是比較慢的。
-
服務的實例是如何從服務中心剔除的:eureka server 要求client端定時進行續約,也就是發送心跳,來證明該服務實例還存活,是健康的,是可以調用的。
-
如果租約超過一定的時間沒有進行續約操作,eureka server端會主動的剔除,這一點即心跳模式。
Eureka參數含義
配置 | 含義 | 默認值 |
---|---|---|
eureka.client.enabled | 是否啓用Eureka Client 默認值:true | true |
eureka.client.register-with-eureka | 表示是否將自己註冊到Eureka Server 默認值:true | true |
eureka.client.fetch-registry | 表示是否從Eureka Server獲取註冊的服務信息默認值:true | true |
eureka.client.serviceUrl.defaultZone | 配置Eureka Server地址,用於註冊服務和獲取服務默認值:http://localhost:8761/eureka | http://localhost:8761/eureka |
eureka.client.registry-fetch-interval-seconds | 默認值爲30秒,即每30秒去Eureka Server上獲取服務並緩存默認值:30 | 30 |
eureka.instance.lease-renewal-interval-in-seconds | 向Eureka Server發送心跳的間隔時間,單位爲秒,用於服務續約默認值:30 | 30 |
eureka.instance.lease-expiration-duration-in-seconds | 定義服務失效時間,即Eureka Server檢測到Eureka Client木有心跳後(客戶端意外下線)多少秒將其剔除默認值:90 | 90 |
eureka.server.enable-self-preservation | 用於開啓Eureka Server自我保護功能默認值:true | true |
eureka.client.instance-info-replication-interval-seconds | 更新實例信息的變化到Eureka服務端的間隔時間,單位爲秒默認值:30 | 30 |
eureka.client.eureka-service-url-poll-interval-seconds | 輪詢Eureka服務端地址更改的間隔時間,單位爲秒。默認值:300 | 300 |
eureka.instance.prefer-ip-address | 表示使用IP進行配置爲不是域名默認值:false | false |
eureka.client.healthcheck.enabled | 默認Erueka Server是通過心跳來檢測Eureka Client的健康狀況的,通過置爲true改變Eeureka Server對客戶端健康檢測的方式,改用Actuator的/health端點來檢測。默認值:false | false |
Eureka常用配置
eureka:
server:
wait-time-in-ms-when-sync-empty: 0 #在eureka服務器獲取不到集羣裏對等服務器上的實例時,需要等待的時間,單機默認0
shouldUseReadOnlyResponseCache: true #eureka是CAP理論種基於AP策略,爲了保證強一致性關閉此切換CP 默認不關閉 false關閉
enable-self-preservation: false #關閉服務器自我保護,客戶端心跳檢測15分鐘內錯誤達到80%服務會保護,導致別人還認爲是好用的服務
eviction-interval-timer-in-ms: 6000 #清理間隔(單位毫秒,默認是60*1000)5秒將客戶端剔除的服務在服務註冊列表中剔除#
response-cache-update-interval-ms: 3000 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上默認30s
response-cache-auto-expiration-in-seconds: 180 #eureka server緩存readWriteCacheMap失效時間,這個只有在這個時間過去後緩存纔會失效,失效前不會更新,過期後從registry重新讀取註冊服務信息,registry是一個ConcurrentHashMap。
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
hostname: 127.0.0.1
lease-renewal-interval-in-seconds: 30 # 續約更新時間間隔(默認30秒),eureka客戶端向服務端發送心跳的時間間隔
lease-expiration-duration-in-seconds: 90 # 續約到期時間(默認90秒)
client:
#註冊到其他eureka
registerWithEureka: false
fetchRegistry: false #爲true時,可以啓動,但報異常:Cannot execute request on any known server ,是否從eureka服務端獲取註冊信息,消費者需要配置true
register-with-eureka: false #表示是否將服務註冊到Eureka服務端,由於自身就是Eureka服務端,所以設置爲false;
fetch-registry: false #表示是否從Eureka服務端獲取服務信息,因爲這裏只搭建了一個Eureka服務端,並不需要從別的Eureka服務端同步服務信息,所以這裏設置爲false;
instance-info-replication-interval-seconds: 10 #更新實例信息的變化到Eureka服務端的間隔時間,單位爲秒
registry-fetch-interval-seconds: 30 #從eureka服務端獲取註冊信息的間隔時間
eureka-service-url-poll-interval-seconds: 300 #輪詢Eureka服務端地址更改的間隔時間,單位爲秒。
service-url:
defaultZone: http://lee:lee@${eureka.instance.hostname}:${server.port}/eureka/
Eureka必須優化參數
eureka.server.responseCacheUpdateIntervalMs = 3000 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上 默認30s
eureka.client.registryFetchIntervalSeconds = 30000 #從eureka服務端獲取註冊信息的間隔時間
eureka.client.leaseRenewalIntervalInSeconds = 30 # 續約更新時間間隔(默認30秒),eureka客戶端向服務端發送心跳的時間間隔
eureka.server.evictionIntervalTimerInMs = 60000 #清理間隔(單位毫秒,默認是60*1000)5秒將客戶端剔除的服務在服務註冊列表中剔除#
eureka.instance.leaseExpirationDurationInSeconds = 90 90 # 續約到期時間(默認90秒)
- 服務發現的時效性變成秒級,幾秒鐘可以感知服務的上線和下線 這樣eurek server差不多就優化好了,我們再優化下client端。
spring:
application:
name: api-gateway
cloud:
config:
discovery:
enabled: true
service-id: CONFIG
profile: dev
eureka:
client:
service-url:
defaultZone: http://lee:[email protected]:8080/eureka
registry-fetch-interval-seconds: 5 #eureka client刷新本地緩存時間,默認30
instance:
hostname: 127.0.0.1
instance-id: 127.0.0.1:9000
lease-expiration-duration-in-seconds: 7 #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位爲秒,超過則剔除(客戶端告訴服務端按照此規則等待自己),默認90
lease-renewal-interval-in-seconds: 5 #Eureka客戶端向服務端發送心跳的時間間隔,單位爲秒(客戶端告訴服務端自己會按照該規則),默認30
Eureka與Zookeeper的區別
CAP,C是一致性,A是可用性,P是分區容錯性。
-
zk是有一個leader節點會接受數據,然後同步到其他的節點,一但leader掛了,要重新選舉leader,這個過程爲了保證C,就犧牲了A,不接用一段時間,但是一個leader選舉好了,就可以繼續寫數據了,保證一致性,即CP
-
eureka是peer模式,可能還沒同步數據過去,結果自己就死了,此時還是可以繼續從別的eureka機器上拉取註冊表,但是可能看到的就不是最新的數據了,但是保證了可用性A,即AP。