SpringCloud-服務註冊中心「Eureka」的介紹與使用
- 2020 年 4 月 19 日
- 筆記
- Java之路, Spring Cloud
Eureka 兩大組件
🚩 Eureka Server:提供服務註冊服務
各個微服務節點通過配置啟動後,會在 Eureka Server 中進行註冊, 這樣 Eureka Server 中的服務註冊表中將會存儲所有可用服務節點的資訊,服務節點的資訊可以在介面中直觀看到。
🚩 Eureka Client:通過服務註冊中心訪問
是一個Java客戶端,用於簡化Eureka Server的交互,客戶端同時也具備一個內置的、 使用輪詢(round-robin)負載 演算法的負載均衡器在應用啟動後,將會向Eureka Server發送心跳(默認周期為30秒)。如果 Eureka Server 在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server 將會從服務註冊表中把這個服務節點移除(默認90秒)。
Eureka Server 搭建
只列出重要部分,詳細程式碼可在 此處 獲取 ~
1、在「註冊中心服務」導入 Maven 依賴
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2、編寫配置文件
server:
port: 7001
eureka:
instance:
# eureka服務端的實例名稱
hostname: localhost
client:
# false表示不向註冊中心註冊自己
register-with-eureka: false
# false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
fetch-registry: false
# 設置與 Eureka Server 交互的地址查詢服務和註冊服務都需要依賴此地址
service-url:
defaultZone: //${eureka.instance.hostname}:${server.port}/eureka/
3、在主啟動類開啟 Eureka 服務註冊功能
@SpringBootApplication
@EnableEurekaServer //開啟服務註冊功能
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}
4、打開瀏覽器輸入://localhost:7001/
,成功進入 Eureka 服務面板即基本配置已完成
Eureka Client 註冊
1、在「服務提供者」添加客戶端的 Maven 依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、添加配置
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: //localhost:7001/eureka # 註冊中心的地址
3、在主啟動類開啟 Eureka 服務端
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class);
}
}
4、進入註冊面板即可發現服務已註冊進來
5、再按照上面的方式,將「服務消費者」註冊進來,自此為止,我們搭建了一個簡單的單機版 Eureka 環境。
單機版 Eureka 的問題
微服務 RPC 遠程服務調用最核心的是什麼?
高可用 !試想,如果你的註冊中心只有一個,它出故障會導致整個微服務環境不可用,所以我們可以通過搭建 Eureka 註冊中心集群,實現負載均衡 + 故障容錯。
Eureka 集群原理說明:
搭建 Eureka 集群
1、為了模擬集群,我們需要修改 host 文件
# SpringCloud Eureka 集群配置
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
2、新建一個項目當作 Eureka 服務註冊中心,配置文件如下
server:
port: 7002
eureka:
instance:
# eureka服務端的實例名稱
hostname: eureka7002.com
client:
# false表示不向註冊中心註冊自己
register-with-eureka: false
# false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
fetch-registry: false
# 設置與 Eureka Server 交互的地址查詢服務和註冊服務都需要依賴此地址
service-url:
defaultZone: //eureka7001.com:7001/eureka/
3、並修改上一個項目的配置,完成兩個註冊中心之間的相互註冊
server:
port: 7001
eureka:
instance:
# eureka服務端的實例名稱
hostname: eureka7001.com
client:
# false表示不向註冊中心註冊自己
register-with-eureka: false
# false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
fetch-registry: false
# 設置與 Eureka Server 交互的地址查詢服務和註冊服務都需要依賴此地址
service-url:
defaultZone: //eureka7002.com:7002/eureka/
4、訪問://eureka7001.com:7001/
和 //eureka7002.com:7002/
5、由於現在有了倆個註冊中心,我們需要將之前的defaultZone
換為如下配置,重新啟動後可看見兩個註冊中心中都有了其他服務
defaultZone: //eureka7001.com:7001/eureka,//eureka7002.com:7002/eureka
6、再新建一個服務提供者,可以直接拷貝前面的程式碼,啟動服務、刷新註冊中心,現在就有了兩個服務提供者
7、此時使用服務消費者不斷調用提供者,是以 輪詢 的負載均衡方式調用
8、可以通過如下配置「服務名稱」和「訪問資訊提示IP地址」
eureka:
instance:
instance-id: payment8001
prefer-ip-address: true #訪問路徑可以顯示ip地址
前提是你引入了 actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
服務發現 Discovery
1、注入 DiscoveryClient
@Autowired
private DiscoveryClient discoveryClient;
2、獲取服務資訊
@GetMapping("/payment/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("serviceId:" + instance.getServiceId() + "\t" + "Host:" + instance.getHost() + "\t" + "port:" + instance.getPort() + "\t" + "uri:" + instance.getUri());
}
return this.discoveryClient;
}
3、在主啟動類上添加@EnableDiscoveryClient
,開啟服務發現
Eureka 自我保護
在 Eureka 註冊中心的頁面會看到這樣的提示,說明 Eureka 進入了保護模式
保護模式主要用於一組客戶端和 Eureka Server 之間存在網路分區場景下的保護。一旦進入保護模式,Eureka Server 將會嘗試保護其服務註冊表中的資訊,不再刪除服務註冊表中的數據,也就是不會註銷任何微服務。
簡單來說就是:某時刻某個微服務不可用了,Eureka 不會立即清理,依然會對該微服務的資訊進行保存;屬於 CAP 理論中的 AP 分支
🎨 為什麼會產生Eureka自我保護機制?
為了防止 EurekaClient 可以正常運行,但是與 EurekaServer 網路不通情況下,EurekaServer 不會立刻 將EurekaClient 服務剔除
🎨 什麼是自我保護模式?
默認情況下,如果 EurekaServer 在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer 將會註銷該實例(默認90秒)。但是當網路分區故障發生(延時、卡頓、 擁擠)時,微服務與EurekaServer之間無法正常通訊,以上行為可能變得非常危險了 —— 因為微服務本身其實是健康的,此時本不應該註銷這個微服務。Eureka通過「自我保護模式」來解決這個問題 —— 當 EurekaServer 節點在短時間內丟失過多客戶端時(可能發生了網路分區故障),那麼這個節點就會進入自我保護模式。
在自我保護模式中,EurekaServer 會保護服務註冊表中的資訊,不再註銷任何服務實例。
它的設計哲學就是寧可保留錯誤的服務註冊資訊,也不盲目註銷任何可能健康的服務實例。一句話講解:好死不如賴活著I
綜上,自我保護模式是一種應對網路異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留)也不盲目註銷任何健康的微服務。使用自我保護模式,可以讓Eureka集群更加的健壯、穩定。
🎨 如何禁用自我保護模式
在註冊中心服務配置中加入以下內容
eureka:
server:
# 關閉自我保護機制,保證不可用服務及時被剔除
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
刷新註冊中心頁面可以看到,提示內容已經變了,自我保護模式已關閉
在其它服務配置中加入以下內容
eureka:
instance:
# Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(默認是30秒)
lease-renewal-interval-in-seconds: 1
# Eureka服務端在收到最後一次心跳後等待時間上限,單位為秒(默認是90秒),超時將剔除服務
lease-expiration-duration-in-seconds: 2
正常啟動服務後,服務出現在註冊中心列表,當我們關閉服務再查看列表,可以看到服務在 2s 內直接被剔除了
Eureka2.0 停更聲明
這是 Eureka 官方的聲明
雖然它停止更新了,現在有了更好的替代品,但其思想是相通的,停更不停用,依然值得我們學習。