微服務不同環境到底該如何部署?最佳實踐是什麼?
來源:WU雙
你們是怎麼部署微服務的?
如何處理不同的環境部署的?
今天給大家帶來我們的一些實踐。
1
一句話來說,微服務部署的最大挑戰是如何保證不同的環境部署程式碼的一致性,以及如何區分不同的部署環境。
作為開發,可能我們大多數時間都在開發程式碼,卻忽略了釋出的重要性,實際釋出才是到使用者手裡的最後一步,這一步做的不好,那麼你的軟體價值則不能很好交付到使用者手裡,作為開發,你自己的體驗也不好。
Docker正式因為改變了部署交付的方式,才引起了革命,產生了如此廣泛的影響。
所以我們需要重視並做好交付這一步。
2
微服務的部署方式有多種,傳統的比如打個Jar包,透過 java -jar 來啟動,在雲端計算時代,更多的則是透過構建Docker映象的方式,透過docker run 來啟動。
這裡的一個主要問題是,如何在不同的環境中去部署相應的服務。
對於一般公司來講,我們會有開發、沙箱、預生產、生產環境,不同的環境,會有不同的配置,當然微服務背景下,我們都會引入配置中心,但不同環境下,還是需要不同的配置中心配置。
那麼如何在不同的環境下去部署?
讓我們來看看幾種解決方案。(說明:以下都是透過構建Docker映象的方式來部署的方案。)
方案一:不同的環境打不同的映象
此種方案透過配合maven profile,maven-antrun-plugin外掛,在不同的環境下,將不同環境的配置檔案覆蓋resources目錄下的配置最後在打成Jar包,然後透過docker-maven-plugin外掛,將應用Jar包構建成Docker映象,推送到不同環境的Docker映象倉庫。
不同環境的部署,只需要到不同環境的Docker映象倉庫中拉取映象,然後啟動就行了。
關鍵步驟資訊如下:
1)pom.xml中提前設定好不同的profile,不同的profile將使用不同的配置檔案進行打包並構建映象。
<!-- 這裡以沙箱環境的映象打包為例 --> <profile> <id>sand</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>validate</phase> <configuration> <target> <move file="./config/sand/bootstrap.yml" tofile="./src/main/resources/bootstrap.yml" overwrite="true"/> <echo>${revision}</echo> <replace file="src/main/resources/bootstrap.yml" token="@version@" value="${revision}"/> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.0.0</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <!-- 映象名稱 --> <imageName>127.0.0.1:5000/${project.artifactId}</imageName> <!-- 指定標籤 --> <imageTags> <imageTag>${revision}</imageTag> </imageTags> <dockerHost>{project.basedir}/src/main/assembly</dockerDirectory> <buildArgs> <APP_NAME>${project.build.finalName}</APP_NAME> </buildArgs> <resources> <resource> <directory>${project.build.directory}</directory> <includes> <include>${project.build.finalName}.jar</include> </includes> </resource> </resources> </configuration> </plugin> </plugins> </build> </profile>
2)maven打包階段指定不同的profile
mvn clean deploy -P sand
上述部署方案整體流程如下圖所示:
上述方案的問題是,需要提前將所有的配置檔案都放在程式碼倉庫中,在環境多的時候不便於維護,特別是在多資料中心的情況下。另外不同的環境實際部署的是不同的映象,不符合Docker的一次構建,處處部署的思想,當然還需要不同的環境部署不同的映象倉庫,也有一定的資源浪費。
方案二:將所有環境打進一個映象,透過spring.profiles.active來生效不同的環境
此種方案是將所有環境都打包到一個映象中,然後在啟動的時候透過Spring的 spring.profiles.active 來生效不同的環境配置,關鍵步驟如下:
1)將所有環境的配置放到一個配置檔案中,或者是放在不同環境的配置檔案中(下面是將所有的配置都放到/src/main/resources/bootstrap.yml檔案中):
server:
port: 8888
spring:
application:
name: my-app
profiles:
# 預設啟用dev環境
active: dev
# 開發環境
---
spring:
config:
activate:
on-profile: dev
cloud:
nacos:
discovery:
server-addr:
metadata:
version: '1.0.0-SNAPSHOT'
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
name: ${spring.application.name}
# 沙箱環境
---
spring:
config:
activate:
on-profile: sand
cloud:
nacos:
discovery:
server-addr:
metadata:
version: '1.0.0-SNAPSHOT'
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
name: ${spring.application.name}
# 生產環境
---
spring:
config:
activate:
on-profile: prod
cloud:
nacos:
discovery:
server-addr:
metadata:
version: '1.0.0-SNAPSHOT'
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
name: ${spring.application.name}
2)啟動的時候,透過啟動指令碼指定不同的active:
JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=sand"
上述部署方案整體流程如下圖所示:
上述方案可以確保不同環境的映象一致性,符合Docker的構建一次,處處部署的思想,當然問題是需要提前將所有環境都放在專案裡,這會導致在環境變化時需要修改程式碼的問題(程式碼和配置沒有完全分離),也會有安全問題,因為你的生產環境地址也暴露無遺。
方案三:將所有環境抽離出環境變數,在應用啟動的時候透過環境變數注入
此種方案利用了Spring透過命令列來指定相關配置的特性,真正實現了程式碼與配置的完全分離。程式碼庫裡不存放任何的環境地址(可以只存放本地開發環境地址),所有的環境地址都透過環境變數的方式注入進去。這樣可以真正做到,一套程式碼,處處執行,即使在新增資料中心,需要重新部署的時候,也不需要修改任何程式碼,直接透過環境變數指定即可。
關鍵步驟如下:
1)Docker部署指令碼在啟動容器時將環境變數注入:
docker run -e SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR="localhost:8840" -d --network=host -v /log/:/log/ ${SERVER_DOCKER}/${SERVICE_NAME}:latest
2)應用啟動指令碼透過環境變數,獲取相應的地址:
# 指定nacos地址JAVA_OPTS="$JAVA_OPTS -Dspring.cloud.nacos.discovery.server-addr=${SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR}"# 指定日誌檔案JAVA_OPTS="$JAVA_OPTS -DLOGBACK_LOG_HOME=${LOGBACK_LOG_HOME}"JAVA_OPTS="$JAVA_OPTS -jar ${DEPLOY_DIR}/${SERVER_NAME}.jar"
上述部署方案整體流程如下圖所示:
上述方案實現了程式碼與配置的真正分離,程式碼庫裡無需存放任何地址(可以指保留開發環境地址),不同的部署環境只要注入不同的環境配置即可。可以稱得上是最佳實踐。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2948939/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 到底什麼是微服務?其實就是DDD領域服務微服務
- 為什麼微服務應該是事件驅動?微服務事件
- 微服務架構最佳實踐微服務架構
- 微服務是什麼?微服務
- 什麼是微服務?微服務
- 什麼是微服務微服務
- 微服務架構到底應該如何選擇?微服務架構
- Linux中什麼是動態網站環境及如何部署Linux網站
- Kubernetes 微服務最佳實踐微服務
- 設計微服務的最佳實踐微服務
- Debian與Ubuntu到底有什麼不同,應該如何選擇?Ubuntu
- Websphere Application Server 環境配置與應用部署最佳實踐WebAPPServer
- 01、什麼是微服務微服務
- 微服務架構(一):什麼是微服務微服務架構
- Gilt如何將微服務部署到AWS環境,介紹ION-Roller微服務
- 有效的微服務:10 個最佳實踐微服務
- 同程旅遊微服務最佳實踐微服務
- SpringCloud 微服務最佳開發實踐SpringGCCloud微服務
- .NET微服務最佳實踐 eShopOnContainers微服務AI
- 微服務快取原理與最佳實踐微服務快取
- 微服務架構十條最佳實踐微服務架構
- 微服務指南走北(一):微服務是什麼微服務
- 小白入門微服務(0) - 什麼是微服務微服務
- 雲原生時代,微服務到底應該怎麼玩兒?微服務
- [譯]Xcode 環境配置最佳實踐XCode
- 什麼是框架?(最佳實踐、專案總結)框架
- SpringBoot微服務安全最佳實踐 - piotrminkowskiSpring Boot微服務
- 測試微服務的4個最佳實踐微服務
- 微服務的【資料庫管理】最佳實踐微服務資料庫
- 微服務環境下,資料如何治理微服務
- 三、微服務環境搭建微服務
- 開發者最佳實踐日•第13期-實踐微服務架構微服務架構
- 面試官靈魂三問:什麼是SOA?什麼是微服務?SOA和微服務有什麼區別?面試微服務
- 什麼是微服務,它要幹啥微服務
- 什麼是環境變數?Python中如何設定環境變數?變數Python
- 微服務是什麼?帶你簡單瞭解微服務微服務
- 軟體開發中的最佳實踐是什麼?
- 微服務思考(01):什麼是微服務?微服務的優勢和劣勢微服務