Spring Cloud | 第七篇: Eureka叢集高可用的配置
一直在網上查閱資料,配置高可用的叢集,看完了發現還是不明白,或者按照文章的內容一步一步去實現發現根本實現不了,真的很懷疑他們寫的時候是否真的自己測試過了還是大家都是轉發來轉發去的,自己弄了好久,發現沒有一個拿來就可以用的,並且裡面很多的東西也沒有講解清楚,於是打算自己寫一篇總結一下。
環境:IDEA2017,Maven(3.3.9),JDK(1.8),SpringBoot(2.0.3)
本篇文章基於我的Spring Cloud的第一篇文章,可以點選直接跳轉,非常簡單,就是新建一個SpringBoot配置成Eureka服務端。
一:Eureka高可用的作用
之所以進行eureka叢集的搭建,在於我們平時的生產環境中,很難保證單節點的eureka服務能提供百分百不間斷的服務,如果eureka無響應了,整個專案應用都會出現問題,因此要保證eureka隨時都能提供服務的情況下,最好的方式就是採用eureka的叢集模式,也就是搭建eureka的高可用,在eureka的叢集模式下,多個eureka server之間可以同步註冊服務,因此,在一個eureka宕掉的情況下,仍然可以提供服務註冊和服務發現的能力,從而達到註冊中心的高可用。
二:搭建高可用叢集
我們使用之前的Mall_EurekaCenter模組進行改造
首先:新增兩個配置檔案分別為application-server1.yml和application-server2.yml
其中application.yml檔案如下:
#註冊中心應用名稱
spring:
application:
name: eureka-server
#使用的配置檔名
profiles:
active: server1
application-server1.yml檔案如下:
#註冊中心執行的埠號 server: port: 8761 #註冊中心應用名稱 #spring: # application: # name: eureka-server #eureka.server.enableSelfPreservation:是否向註冊中心註冊自己 #通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server. eureka: # server: # enableSelfPreservation: false instance: hostname: server1 prefer-ip-address: false # ip-address: 172.193.225.185 # instance-id: ${spring.cloud.client.ipAddress}:${server.port} client: fetch-registry: true//一定要設定為true或者不寫,否則會出現unavailable-replicas register-with-eureka: true//一定要設定為true或者不寫,否則會出現unavailable-replicas service-url: defaultZone: http://server2:8762/eureka/
application-server2.yml檔案如下:
#註冊中心執行的埠號 server: port: 8762 #註冊中心應用名稱 #spring: # application: # name: eureka-server #eureka.server.enableSelfPreservation:是否向註冊中心註冊自己 #通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server. eureka: # server: # enableSelfPreservation: false instance: hostname: server2 prefer-ip-address: false # ip-address: 172.193.225.185 # instance-id: ${spring.cloud.client.ipAddress}:${server.port} client: fetch-registry: true//一定要設定為true或者不寫,否則會出現unavailable-replicas register-with-eureka: true//一定要設定為true或者不寫,否則會出現unavailable-replicas service-url: defaultZone: http://server1:8761/eureka/
由於我們的eureka.instance.hostname分別配置成了server1和server2,所以需要去修改本機的hosts檔案。
我們前面講過如何在IDEA當中多次啟動同一個工程,我們只需要修改application.yml檔案當中的spring.profiles.active分別為server1和server2,分別啟動專案,訪問各自的埠,頁面如下:
http://localhost:8761/:
http://localhost:8762/:
三:搭建過程當中碰到的問題
問題一:eureka.instance.hostname我單獨使用的時候配置的時候都是使用localhost,你這裡使用的是server1和server2,這樣就需要去修改hosts檔案太麻煩了,能不這麼麻煩嗎?
假如需要搭建eureka叢集的話,那麼eureka.instance.hostname不能重複,否則叢集失敗,所以不能為localhost或者ip地址。在測試中我剛開始使用的是localhost去進行叢集發現無法成功。service-url.defaultZone寫的地址記得使用如下格式:http://其他eurekaServer的hostname:其它eurekaServer的port/eureka/,多臺叢集這樣的格式用逗號隔開。
問題二:你的eureka.instance.prefer-ip-address為false,這樣就會導致我們看到的服務例項不顯示ip,怎麼辦?
我把這個值設定為true,結果在http://localhost:8761/頁面上發現,另外一個註冊中心失效了。
問題三:分散式註冊中心出現在unavaliable-replicas上面
把eureka.instance.prefer-ip-address為false
把eureka.client.fetch-registry設定為true
把eureka.clinet.register-with-eureka設定為true
四:建立eureka client向兩個註冊中心進行註冊
我們使用之前的工程,改造Mall_ManagerService,只需要把application.yml檔案當中的註冊中心的地址更改一下就可以:
啟動該工程,我們訪問http://localhost:8761/和http://localhost:8762/,可以看到能夠正常註冊服務。
五:eureka同步機制
由於eureka之間有同步機制,我們可以簡化一下這一配置。多個eureka例項需要兩兩互相註冊,就可以實現叢集中節點完全對等的效果,此時只要服務註冊到其中一個註冊中心,就會同步到其他註冊中心。我們可以在服務當中看下只向一個註冊中心註冊,看下效果。
更改Mall_ManagerService的配置檔案,只填寫一個註冊中心的地址。
這個時候我們再去訪問http://localhost:8762/,發現一樣可以看到Mall_ManagerService的資訊。
但是這樣做有一個缺點就是,當我們把服務給關掉之後,過段時間我們發現,我們服務註冊的註冊中心server1已經進入保護狀態,但是服務server2卻把服務給剔除掉了。
http://localhost:8761/
http://localhost:8762/
所以我們把服務註冊到eureka叢集當中,儘量註冊到所有的eureka服務端上,以實現高可用。