①SpringCloud 實戰:引入Eureka元件,完善服務治理
阿新 • • 發佈:2020-11-24
### 簡介
Netflix Eureka 是一款由 Netflix 開源的基於 REST 服務的註冊中心,用於提供服務發現功能。Spring Cloud Eureka 是 Spring Cloud Netflix 微服務套件的一部分,基於 Netflix Eureka 進行了二次封裝,主要負責完成微服務架構中的服務治理功能。
Spring Cloud Eureka 是一個基於 REST 的服務,並提供了基於 Java 的客戶端元件,能夠非常方便的將服務註冊到 Spring Cloud Eureka 中進行統一管理。
### 部署 Eureka Server
1. 建立一個名為 eureka-server 的 Spring Cloud 的專案(略)
2. 引入 eureka-server 依賴(maven)
```xml
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
```
3. 開啟 EurekaServer
在啟動類上新增 `@EnableEurekaServer`註解,開啟 EurekaServer 的自動裝配功能。
4. 修改服務埠為8761
5. 修改 register-with-eureka 配置
新增一個`eureka.client.register-with-eureka=false`的配置,作為EurekaServer可以不將自己的例項註冊到 Eureka Server 中,如果是叢集部署設定為true(不配置預設值也是true)。
6. 修改 `fetch-registry` 配置
新增一個 eureka.client.fetch-registry=false 的配置,表示不從 Eureka Server 中獲取 Eureka 的登錄檔資訊,如果是叢集部署設定為true(不配置預設值也是true)。
7. 新增defaultZone配置
新增一條配置`eureka.client.service-url.defaultZone=http://localhost:8761/eureka/`(如果不加這個的話又自定義了埠,可能會報錯Connect to localhost:8761 timed out)
8. 啟動 Eureka Server,訪問 [http://localhost:8761/](http://localhost:8088/),如果順利的話可以看到如下成功頁面
![](https://img2020.cnblogs.com/blog/709068/202011/709068-20201124141416546-30569584.png)
至此,一個簡單的Eureka註冊中心就完成了,後面實戰中的 Eureka Client 都會註冊到這個註冊中心。上面的demo只是一個單機部署,接下里我們看看我們要部署多個Eureka節點時怎麼做。
### **Eureka Server 叢集部署**
叢集部署一般有兩種情況,一是偽叢集部署,二是真正的叢集部署。
叢集部署,我們可以在多臺物理機上部署,這樣多個例項可以用同一個埠,不會出現偽叢集埠衝突的問題,更推薦這種方式,效能更高,穩定性也更好。
偽叢集部署一般說的是在同一臺物理機器上部署多個節點,這時候埠就必須不一樣,否則啟動的時候會出現埠衝突;
**偽叢集部署示例:**
假設要部署3個節點:master/slave1/slave2
1. 在application.yml配置定義三個節點的埠:
```xml
port:
master: 8761
slave1: 8762
slave2: 8763
```
2. 我們可以分別建立三個配置檔案application-master.yml、application-slave1.yml、application-slave2.yml,三個配置檔案除了有衝突的地方埠不一樣,其他配置完全一樣
```xml
# application-master.yml
server:
port: ${port.slave1} # 服務埠
# application-master.yml
server:
port: ${port.slave1} # 服務埠
# application-slave2slave2.yml
server:
port: ${port.slave2} # 服務埠
# 以下配置三個配置檔案都一樣
eureka:
client:
register-with-eureka: true #不將自己的例項註冊到 Eureka Server
fetch-registry: true #不從 Eureka Server 中獲取 Eureka 的登錄檔資訊
service-url:
defaultZone: http://127.0.0.1:${port.master}/eureka/,http://127.0.0.1:${port.slave1}/eureka/,http://127.0.0.1:${port.slave2}/eureka/
instance:
hostname: eureka-server
server:
enable-self-preservation: true # 開啟自我保護機制,預設也是開啟的
```
3. IDEA 分別以三個不同的profiles啟動
![](https://img2020.cnblogs.com/blog/709068/202011/709068-20201124141459758-1401235544.png)
4. 訪問 [http://localhost:8761/](http://localhost:8761/) 或者 [http://localhost:8762/](http://localhost:8761/) 或者 [http://localhost:8761/](http://localhost:8761/),出現以下類似頁面則代表成功
![](https://img2020.cnblogs.com/blog/709068/202011/709068-20201124141513610-788851847.png)
觀察上面的頁面,發現 Eureka Server 節點均出現在 unavailable-replicas 下,說明叢集搭建還是失敗了,那這個問題怎麼解決呢?
1. 在`host`新增以下配置
```xml
127.0.0.1 eureka-server-master
127.0.0.1 eureka-server-slave1
127.0.0.1 eureka-server-slave2
```
2. 修改三個配置檔案的`defaultZone`資訊
```xml
eureka:
client:
service-url:
defaultZone: http://eureka-server-master:${port.master}/eureka/,http://eureka-server-slave1:${port.slave1}/eureka/,http://eureka-server-slave2:${port.slave2}/eureka/
```
3. 配置`eureka.instance.hostname`資訊(尤其是在同一臺物理機上配置三個節點時,需要修改為不同的host)
```xml
eureka:
instance:
hostname: eureka-server-master
eureka:
instance:
hostname: eureka-server-slave1
**eureka:
instance:
hostname: eureka-server-slave2
```
4. 重新啟動,訪問[http://localhost:8761/](http://localhost:8761/) ,其他兩個節點君出現在 available-replicas 選項
![](https://img2020.cnblogs.com/blog/709068/202011/709068-20201124141534356-1823256569.png)
注意:如果執行完上面還是出現在,請檢查是否配置了 prefer-ip-address = true,true #以IP地址註冊到服務中心,相互註冊使用IP地址,如果是在一臺物理機上,IP都是一個,所以建議設定成false,或者不配置再試試。
### 部署 Eureka Client
1. 建立一個名為eureka-client 的SprintBoot的專案(略)
2. 引入eureka-client依賴(maven)
```xml
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
```
3. 引入spring-boot-starter-web依賴,如果沒有加上spring-boot-starter-web,服務無法正常啟動
```xml
org.springframework.boot
spring-boot-starter-web
```
4. 開啟 EurekaClient
在啟動類上加入註解`@EnableEurekaClient`,用於啟用Eureka發現配置
5. 配置埠為8081
```xml
server.port = 8081
port.master = 8761
port.slave1 = 8762
port.slave2 = 8763
```
6. 配置註冊中心地址
新增配置 `eureka.client.serviceUrl.defaultZone=http://eureka-server-master:${port.master}/eureka/,http://eureka-server-slave1:${port.slave1}/eureka/,http://eureka-server-slave2:${port.slave2}/eureka/`
7. 啟動服務,重新整理 [http://localhost:8761/](http://localhost:8088/) 頁面,如果看到了EUREKA-CLIENT應用則表示註冊成功
![](https://img2020.cnblogs.com/blog/709068/202011/709068-20201124141553558-1061251503.png)
### **Eureka自我保護機制**
自我保護機制是為了避免因網路分割槽故障而導致服務不可用的問題。具體現象為當網路故障後,所有的服務與 Eureka Server 之間無法進行正常通訊,一定時間後,Eureka Server 沒有收到續約的資訊,將會移除沒有續約的例項。這個時候正常的服務也會被移除掉,所以需要引入自我保護機制來解決這種問題。
當服務提供者出現網路故障,無法與 Eureka Server 進行續約,Eureka Server 會將該例項移除,此時服務消費者從 Eureka Server 拉取不到對應的資訊,實際上服務提供者處於可用的狀態,問題就是這樣產生的。
**開啟自我保護機制**
```xml
eureka.server.enable-self-preservation=true # 開啟自我保護機制,預設也是開啟的
```
當服務提供者出現網路故障,無法與 Eureka Server 進行續約時,雖然 Eureka Server 開啟了自我保護模式,但沒有將該例項移除,服務消費者還是可以正常拉取服務提供者的資訊,正常發起呼叫。
但是自我保護機制也有不好的地方,如果服務提供者真的下線了,由於 Eureka Server 自我保護還處於開啟狀態,不會移除任務資訊,當服務消費者對服務提供者 B 進行呼叫時,就會出錯。
自我保護模式有利也有弊,但我們建議在生產環境中還是開啟該功能,預設配置也是開啟的。
完整程式碼例項:
1. [Eureka Server 程式碼例項](https://github.com/Admol/learning_examples/tree/master/SpringCloud-Demo/eureka-server)
2. [Eureka Client 程式碼示例](https://github.com/Admol/learning_examples/tree/master/SpringCloud-Demo/eurela-client)
### 總結
1. 使用`@EnableEurekaServer` 註解實現註冊中心
2. 使用`@EnableEurekaClient` 註冊到註冊中心
3. Eureka Server 叢集部署的時候需要保證`register-with-eureka`和 `fetch-registry` 為true,單機部署可以為false
4. 生產環境建議開啟自我保護機制