2017年3月15日 星期三

Spring Cloud 搭配Docker (swarm mode) 建置 Eureka Cluster

這問題卡了我好幾天...後來發現是我觀念上有,可惡超浪費時間的,本來想說很簡單的>_<

事情是這樣的,我利用docker service create --mode global(swarm mode , 1 manager node and 2 worker node) 建好Eureka Peer to Peer後(共三個 Eureka Server) ,但到Eureka server UI 看,發現其他兩個node一直顯示在unavailable-replicas 的區塊, 雖然查了很多資料,網路上甚至有人說...功能正常就好(意旨即使把其中一個server關掉,其他eureka也會做cluster), 但其實這只是用docker 的load balance機制應變(前面講了我是用global模式),並不是真正eureka的 cluster模式, 雖然乍看之下功能"好像正常",但其實根本不正常呀,因為會發現微服務會一直瞬斷再重連,是有問題的。

原因是因為我們在eureka server 設定檔分別設置了defaultZone三種不同的profile(分別是manager and worker node),但如果是用global mode,雖然會在三個節點起eureka server container,但事實上三台節點所使用的eureka profile是同一份,根本不是available-repicas,所以UI顯示的當然是unavailable-replicas ,不要懷疑,就是整個設定上有問題。

所以如果想在swarm mode下使用docker 建置eureka cluster,應該正確讓三個節點分別解正確的吃到不同的profile設定,怎麼做勒?其實很簡單。
就是使用docker service create 建立三個service (不要使用global mode),並且分別指定service 的節點及所要使用的profile即可。

eureka server參考設定檔:
---
spring:
  profiles: docker1
server:
  port: 8761
eureka:
  instance: 
    preferIpAddress: true
    hostname: docker1
  server:
    enableSelfPreservation: true
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://docker2:8762/eureka/,http://docker3:8763/eureka/

---
spring:
  profiles: docker2
server:
  port: 8762
eureka:
  instance:
    preferIpAddress: true
    hostname: docker2
  server:
    enableSelfPreservation: true
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://docker1:8761/eureka/,http://docker3:8763/eureka/

---
spring:
  profiles: docker3
server:
  port: 8763
eureka:
  instance:
    preferIpAddress: true
    hostname: docker3
  server:
    enableSelfPreservation: true 
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://docker1:8761/eureka/,http://docker2:8762/eureka/


config server 參考設定檔:
...
eureka:
  instance:
    # 心跳时间,即服务续约间隔时间(預設为30s)
    leaseRenewalIntervalInSeconds: 20
    # 发呆时间,即服务续约到期时间(預設为90s)
    lease-expiration-duration-in-seconds: 60
    prefer-ip-address: false
  client:
    registryFetchIntervalSeconds: 5
    serviceUrl:
       defaultZone: http://docker1:8761/eureka/,http://docker2:8762/eureka/,http://docker3:8763/eureka/
    healthcheck:
      enabled: true

參考指令:
docker service create -p 8761:8761 --constraint node.hostname==docker1 -e spring.profiles.active=docker1 --network mynet --name demo-registry1 docker1:9527/demo-registry:v1

docker service create -p 8762:8762 --constraint node.hostname==docker2 -e spring.profiles.active=docker2 --network mynet --name demo-registry2 docker1:9527/demo-registry:v1

docker service create -p 8763:8763 --constraint node.hostname==docker3 -e spring.profiles.active=docker3 --network mynet --name demo-registry3 docker1:9527/demo-registry:v1



成功畫面:

PS. 如果還是在unavailable-replicas,請確認registerWithEureka及fetchRegistry:是否有設置為true。

沒有留言:

張貼留言