Spring Eureka 本地Docker叢集部署
- 故事背景
最近因為產線使用的服務與發現服務,使用的是Spring Cloud Eureka叢集部署,為了以後除錯產線的問題,想在本地搭建和產線一樣的環境。產線的所有服務都是基於K8s和Docker部署,所以本地也想將Eureka部署到本地的Docker環境。
- Eureka介紹
Eureka 屬於 Spring Netflix的一個子專案,主要是為了實現服務的註冊與發現,如果我們做微服務開發,這個功能是必不可少的。具有類似功能的 Spring 子專案還有 Spring Consul、Zookeeper 和 阿里的 Nacos,後面如果使用到再做介紹。
- Spring配置
首先,我們要建立一個Spring boot專案,建議使用Idea去建立,比較方便,如下圖:
直接Next,然後設定自己專案資訊,然後選擇pom的依賴項,如下圖:
直接Next,然後finished, 這裡推薦使用父子module的專案管理方式。專案建立完成以後,進行服務的配置,首先,需要在Application啟動類上加註解 @EnableEurekaServer,如下圖:
然後,進行yml檔案的配置,因為我們要部署叢集,所以我們建立3個yml檔案,然後檔案中設定不同的埠來啟動,如下圖:
yml檔案內容如下:
application-eureka01.yml ------------------------------------------------------------ spring: application: name: eureka server: port: 7001 eureka: instance: #eureka服務端的例項名稱 hostname: eureka01 client: # false表示不向註冊中心註冊自己 register-with-eureka: true # false表示自己端就是註冊中心,我的職責就是維護服務例項,並不需要去檢索服務 fetch-registry: true service-url: #設定與Eureka Server互動的地址查詢服務和註冊服務都需要依賴這個地址(單機)。 defaultZone: http://eureka02:7002/eureka/,http://eureka03:7003/eureka/ application-eureka02.yml ------------------------------------------------------------ spring: application: name: eureka server: port: 7002 eureka: instance: #eureka服務端的例項名稱 hostname: eureka02 client: # false表示不向註冊中心註冊自己 register-with-eureka: true # false表示自己端就是註冊中心,我的職責就是維護服務例項,並不需要去檢索服務 fetch-registry: true service-url: #設定與Eureka Server互動的地址查詢服務和註冊服務都需要依賴這個地址(單機)。 defaultZone: http://eureka01:7001/eureka/,http://eureka03:7003/eureka/ application-eureka03.yml ------------------------------------------------------------ spring: application: name: eureka server: port: 7003 eureka: instance: #eureka服務端的例項名稱 hostname: eureka03 client: # false表示不向註冊中心註冊自己 register-with-eureka: true # false表示自己端就是註冊中心,我的職責就是維護服務例項,並不需要去檢索服務 fetch-registry: true service-url: #設定與Eureka Server互動的地址查詢服務和註冊服務都需要依賴這個地址(單機)。 defaultZone: http://eureka01:7001/eureka/,http://eureka02:7002/eureka/
然後,在Serives View裡面建立3個啟動配置,並且分別設定 Active profiles,如下圖:
最後,也是比較容易忘記的一步,記得修改本地的hosts檔案,新增一行 :
127.0.0.1 eureka01 eureka02 eureka03
啟動3個Eureka 服務,然後訪問:http://localhost:7001/,你會看到如下頁面,說明你已經配置成功:
- Docker配置
我本地是安裝的windows版本docker,主要是為了節省記憶體,如果在linux下安裝還需要裝一個虛擬機器工具。而且windows版本的docker用起來也蠻方便的,很多操作可以在Dashboard裡面操作,省去了很多不斷重複的命令,特別是看日誌和進入容器。具體安裝過程很簡單,這裡就不作說明。在這裡首先我們要製作Dockerfile,製作好放到和pom檔案的同目錄下,內容如下圖:
# 指定基礎映象,這是分階段構建的前期階段 FROM openjdk:8u212-jdk-stretch as builder # 執行工作目錄 WORKDIR application # 配置引數 ARG JAR_FILE=target/*.jar # 將編譯構建得到的jar檔案複製到映象空間中 COPY ${JAR_FILE} application.jar # 通過工具spring-boot-jarmode-layertools從application.jar中提取拆分後的構建結果 RUN java -Djarmode=layertools -jar application.jar extract # 正式構建映象 FROM openjdk:8u212-jdk-stretch WORKDIR application # 前一階段從jar中提取除了多個檔案,這裡分別執行COPY命令複製到映象空間中,每次COPY都是一個layer COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
然後,編譯打包專案:
mvn clean package -U -DskipTests
這時會在target目錄下看到 eureka-0.0.1-SNAPSHOT.jar 。接下來我們需要構建docker image,我們預設在Dockerfile的目錄下,命令如下:
docker build -t eureka:0.0.8 .
此時我們可以用 Windows PowerShell 執行如下命令,去看一下我們構建的image,並且依次啟動3個eureka服務:
#檢視所有映象
docker images
#啟動3個eureka服務
docker run --name eureka01 -d -p 7001:7001 eureka:0.0.1 --spring.profiles.active=eureka01
docker run --name eureka02 -d -p 7002:7002 eureka:0.0.1 --spring.profiles.active=eureka02
docker run --name eureka03 -d -p 7003:7003 eureka:0.0.1 --spring.profiles.active=eureka03
此時我們可以在Docker Dashboard看到,我們啟動的容器,但是此時容器之間是無法通過服務名相互訪問的,所以在容器console中我們可以看到拒絕連線的報錯:
接下來有重要一步驟就是,需要建立自己的一個bridge network,然後將eureka服務連線這個network中,因為預設docker的containers相互是可以通過IP相互訪問,但是不能夠通過hostname相互訪問,docker的containers經常會動態改變,所以在這裡我們就需要用到一個自定義bridge網路,它在容器之間提供了自動DNS解析的功能,具體原因可以參考這篇文章:https://juejin.im/post/6844903847383547911 。
# 建立一個自定義的 bridge network,指定網段的時候注意,別和其它網絡卡的網段衝突 docker network create --subnet=172.19.0.0/16 mynetwork #檢視建立的network資訊 docker network inspect mynetwork #刪除網絡卡命令 #docker network rm mynetwork # 將eureka服務加入mynetwork網路中 docker network connect mynetwork eureka01 docker network connect mynetwork eureka02 docker network connect mynetwork eureka03 #再次檢視network的資訊,你會看到每個eureka服務在 mynetwork 中分配的IP資訊 docker network inspect mynetwork
此時,我們再次檢視容器的控制檯,錯誤就會消失,我們再次訪問 http://localhost:7001/ 可以看到eureka cluster已經正常執行起來。
在開發中有同樣需求的同學,如果遇到什麼問題可以留言交