關(guān)于SpringBoot微服務(wù)發(fā)布與部署的三種方式
SpringBoot 微服務(wù)部署流程
基于 SpringBoot 的微服務(wù)開發(fā)完成之后,現(xiàn)在到了把它們發(fā)布并部署到相應(yīng)的環(huán)境去運行的時候了。
SpringBoot 框架只提供了一套基于可執(zhí)行 jar 包(executable jar)格式的標(biāo)準發(fā)布形式,但并沒有對部署做過多的界定,而且為了簡化可執(zhí)行 jar 包的生成,SpringBoot 提供了相應(yīng)的 Maven 項目插件:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- 其他插件定義 --> </plugins> </build>
然后只要我們運行 mvn package,當(dāng)前 SpringBoot 項目就會被打包成一個包含了其所有項目依賴以及該項目本身的可執(zhí)行 jar 包,通過 scp 或者 rsync 等方式將這個可執(zhí)行 jar 包部署到目標(biāo)環(huán)境的服務(wù)器之后,就可以通過 java-jar your-project.jar 啟動 SpringBoot 應(yīng)用了。
整個流程看起來很簡單,也很符合大部分開發(fā)人員的認知,但是,相對于一套較為嚴謹?shù)能浖桓读鞒虂碚f,以上流程則難免過于粗糙了。
軟件的發(fā)布和部署可以有多種不同的形式,這更多由軟件項目的屬性決定,比如:
- 這個項目使用的是什么語言?
- 這個項目屬于類庫項目還是可獨立運行的項目?
- 這個項目是面向什么平臺和環(huán)境的項目?
此外,我們希望使用什么樣的形式進行軟件的交付,這里則涉及生態(tài)管理以及技術(shù)選型的喜好等因素,所以,為了降低講解的復(fù)雜度,我們還是先將發(fā)布和部署分開來說吧。
首先,大家應(yīng)該都知道,發(fā)布并不等于部署,這是兩個階段的事情,如圖 1 所示。
圖 1 發(fā)布與部署示意圖
發(fā)布一般是將項目以指定的格式打包成某種可直接交付的形式,然后放置到預(yù)先指定的交付地點。
比如對于 Java 類庫(Java Library)來說,我們一般將其打包成 jar 包,然后 mvn deploy 到公司內(nèi)部的 Maven 倉庫中(Maven Repository),像 Nexus Repository Manager 或者 JFrog Artifactory 以及 Apache Archiva。
而對于可獨立運行的程序,比如 SpringBoot 微服務(wù)或者一般的 Java Standalone 程序,我們既可以將它們打包成 RPM、DEB 等面向特定目標(biāo)系統(tǒng)的發(fā)布形式,也可以將它們制作成一個個的 docker images,然后將制作完成的發(fā)布成品存儲到相應(yīng)的倉庫中(Repository)去。
部署一般緊接著發(fā)布完成之后進行,它的主要職能就是將已經(jīng)發(fā)布好的成品從倉庫中拿出來,然后分發(fā)到目標(biāo)環(huán)境的指定資源池(比如物理機結(jié)點,虛擬機結(jié)點,docker 宿主機等),并最終啟動服務(wù)。
軟件成品分發(fā)的手段和工具可以有很多種,從最常見的 scp、rsync,到 Chef、Puppet,進而再到最新的 saltstack、ansible 等,一般根據(jù)團隊對這些工具的把控力度和喜好進行選型。
下面我們就幾種典型的發(fā)布和部署形式跟大家一起探索相應(yīng)的實踐。
spring-boot-starter 的發(fā)布與部署方式
spring-boot-starter(s)屬于 Java 類庫性質(zhì)的組件,只被其他可獨立運行的程序依賴使用,自身不可獨立運行,對于這種性質(zhì)的軟件實體,我們一般將其發(fā)布到公司內(nèi)部的軟件倉庫或者以開源形式發(fā)布到 Maven 的中央倉庫(Maven Central Repository)。
下面我們就以 spring-boot-starter-metrics 為例,向大家展示如何將類似 spring-boot-starter-metrics 這樣的 Java 類庫發(fā)布到自己公司內(nèi)部搭建的 Nexus 服務(wù)器上。
首先,你要有一套已經(jīng)搭建完成并運行的 Nexus 服務(wù)器,然后我們需要對 spring-boot-starter-metrics 的 pom.xml 附加一點兒發(fā)布相關(guān)的內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.keevol</groupId> <artifactId>spring-boot-starter-metrics</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-starter-metrics</name> <description>auto configuration module for dropwizard metrics</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <distributionManagement> <repository> <id>deployment</id> <name>internal repository for releases</name> <url>http://{內(nèi)部nexus服務(wù)器地址}/nexus/content/repositories/ releases/</url> </repository> <snapshotRepository> <id>deployment</id> <name>internal repository for snapshots</name> <url>http://{內(nèi)部nexus服務(wù)器地址}/nexus/content/repositories/ snapshots/</url> </snapshotRepository> </distributionManagement> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <metrics.version>3.1.2</metrics.version> </properties> <!--其他配置 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>${metrics.version}</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-annotation</artifactId> <version>${metrics.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.7</version> </dependency> </dependencies> </project>
主要關(guān)注我們添加的 distributionManagement 相關(guān)內(nèi)容,用于將我們的當(dāng)前項目與內(nèi)部的 Nexus 服務(wù)器進行關(guān)聯(lián),這樣,就可以將當(dāng)前項目不同階段的成品(比如 SNAPSHOT 版本或者 RELEASE 版本)發(fā)布到特定的倉庫路徑下。
但是,只是在項目的 pom.xml 中添加 distributionManagement 相關(guān)內(nèi)容還不夠,對發(fā)布服務(wù)器的安全管控等敏感信息不能與 pom.xml 一同公開,所以,還需要在 ~/.m2/settings.xml 配置文件中添加 Nexus 服務(wù)器訪問和認證信息:
<server> <id>deployment</id> <username>deployment</username> <password>********</password> </server>
因為我們前面 distributionManagement 定義的 repository 和 snapshotRepository 的 id 都是 deployment,所以,這里的 server 的 id 也是匹配性地指定為 deployment,至于 username 和 password,則完全是我們內(nèi)部的 nexus 服務(wù)器對應(yīng)的安全認證用的用戶名和密碼啦。
將內(nèi)部 Nexus 服務(wù)器的認證信息放到 maven 的 settings.xml 中并非什么好的實踐,純粹是為了便利性而犧牲安全性,二者之間需要根據(jù)情況做出權(quán)衡,如果對安全性要求比較高的公司或者組織,最好將這些認證信息移除,并只在管控的范圍內(nèi)使用。
比如將這些認證信息回收到發(fā)布和部署平臺這一可控的小范圍環(huán)境中,而所有開發(fā)人員使用的 settings.xml 屬于“消毒”后無安全認證等敏感信息的版本。
當(dāng) pom.xml 中的 distributionManagement 以及 settings.xml 中對應(yīng)的 server 設(shè)定都準備好之后,我們就可以直接 mvn deploy 將 spring-boot-starter-metrics 或者類似的 Java Library 項目發(fā)布到內(nèi)部 Nexus 倉庫了。
對于 Java 類庫類型的項目來說,并無明確的部署過程,如果說有,也是存在于可獨立運行項目的開發(fā)過程中,比如使用 lib 目錄或者結(jié)合 Ant“部署”為項目的依賴,或者直接享受 maven、gradle、sbt 等編譯工具提供的“透明”的依賴部署過程。
基于RPM的發(fā)布與部署方式
部署的目標(biāo)服務(wù)器從硬件到系統(tǒng)軟件,一般情況下都應(yīng)該是盡量相同,這與軟件的標(biāo)準化目的相同,一個是可以減少應(yīng)對不同類型實體的復(fù)雜度,另一個就是標(biāo)準化硬件和軟件之后,就可以通過工具批量化以“邊際成本遞減”近乎為 0 的做法來提升效率,減少成本。
所以,對于大部分互聯(lián)網(wǎng)公司來說,在硬件標(biāo)準化的基礎(chǔ)上,還會使操作系統(tǒng)盡量統(tǒng)一,比如大多數(shù)都是使用穩(wěn)定性和可靠性經(jīng)過長期驗證過的 Red Hat CentOS 系統(tǒng),而 CentOS 本身經(jīng)過長期的沉淀也有一套自己的系統(tǒng)管理工具,比如像 YUM 或者 RPM 這樣的系統(tǒng)包依賴管理器(Debian/Ubuntu 等 Linux 發(fā)行版也有對應(yīng)的 deb 形式的包管理器)。
像 RPM 這樣的包管理器對系統(tǒng)軟件包的依賴和配置提供了很好的支持,如果我們的微服務(wù)等可獨立執(zhí)行實體要部署到像 CentOS 這樣的目標(biāo)環(huán)境中,使用 RPM 完成微服務(wù)的發(fā)布和部署,對于運維人員來說幾乎就是無縫銜接的。
而且,對于 SpringBoot 微服務(wù)來說,單單一個可執(zhí)行的 jar 包實際上是遠遠無法達到發(fā)布和部署要求的,如果只是發(fā)布一個可執(zhí)行的 jar 包,那就意味著在部署階段,運維要做更多的事情來彌補某些缺失,比如:
- 啟動參數(shù)是否調(diào)整?
- 配置文件是否修改?
- 安裝部署結(jié)構(gòu)如何規(guī)范?
- 資源的對接和映射要不要做?
但是,如果我們能夠?qū)⒄麄€軟件交付體系標(biāo)準化和規(guī)范化,然后通過 RPM 這樣的發(fā)布形式將這些標(biāo)注和規(guī)范固化到發(fā)布包中,那么,整個部署過程就可以簡化為一條命令,這其實也是使用 RPM 這種系統(tǒng)原生包管理工具完成交付部署的好處:自動化的 orcherstration,減少不必要的人工干預(yù)中間環(huán)節(jié)。
使用 RPM 發(fā)布 SpringBoot 微服務(wù),我們簡單將這一個過程劃分為幾步,如圖 2 所示。
圖 2 使用 RPM 交付的 SpringBoot 微服務(wù)發(fā)布流程圖
首先,我們需要有一個特定的編譯和項目構(gòu)建環(huán)境,可以不管這個編譯和項目構(gòu)建環(huán)境是搭建在本地(比如你的開發(fā)機上),還是搭建在特定的一臺服務(wù)器上,但這個編譯和項目構(gòu)建環(huán)境需要安裝 rpmbuild,用來構(gòu)建 rpm 包。
其次,我們不推薦 RPM 編譯和構(gòu)建的過程使用某些定義在項目編譯腳本中的插件來完成,這樣會讓一些通用的邏輯散落在所有需要發(fā)布的項目中而不好治理。所以,我們建議使用一個外部化的獨立的編譯服務(wù)器完成整個 SpringBoot 微服務(wù)的 RPM 發(fā)布和部署。
SpringBoot 微服務(wù)的 rpmbuild 腳本構(gòu)建過程主要分幾個主要步驟(如圖 2 中 1 所標(biāo)注):
1)調(diào)用標(biāo)準的 mvn package 完成可執(zhí)行 jar 包的打包。
2)根據(jù)軟件交付規(guī)范,構(gòu)建標(biāo)準發(fā)布格式的 rpm 包,如下所示:
- 使用 bin 目錄存放根據(jù)腳本模板以及環(huán)境變量生成的啟停腳本。
- 使用 config 目錄(SpringBoot 默認文件系統(tǒng)中的配置目錄名)或者 conf 目錄存放特定的配置文件。
- 使用 docs 目錄存放文檔。
- 使用 agents 目錄存放某些 javaagent。
- ……
3)在標(biāo)準發(fā)布格式的基礎(chǔ)上,生成從標(biāo)準發(fā)布格式到具體目標(biāo)環(huán)境的映射。
比如原來應(yīng)用的日志是默認打印到當(dāng)前項目部署目錄,而根據(jù)要求,我們希望打印到 /var/logs/{projectId}/ 或者其他服務(wù)器磁盤容量分配更大的分區(qū),這個時候,可以在 rpmbuild 過程中指定安裝類似的安裝規(guī)則。
下面是一個簡化的 SpringBoot 微服務(wù)的 rpmbuild 腳本定義:
Summary: metrics autoconfigure module for spring boot applicationName: spring-boot-starter-metricsVersion: {version}Release: 1Copyright: ...Group: Applications/ProductivitySource: ...URL: ...Distribution: Vendor: KEEp eVOLution, Inc.Packager: Darren <afoo@keevol.com>%description%prep%buildgit clone .... # 檢出代碼到本地cd {project folder}mvn package ...%install%clean%files/{install_location}/{projectId}/bin/start.sh/{install_location} /{projectId}/bin/stop.sh/{install_location}/{projectId}/agents/jolokia-jvm-1.3.1-agent.jar...%attr(755, user, group) /{install_location}/{projectId}/agents/jolokia-jvm-1.3.1-agent.jar...%doc%changelog
然后需要調(diào)用 rpmbuild 的 spec 定義完成最終 rpm 包的構(gòu)建:
rpmbuild -bb {projectId}.spec#
然后 scp or sftp 生成的 rpm 包到指定的 rpm 倉庫 我們可以像上面那樣直接執(zhí)行 rpmbuild 命令完成最終的 rpm 包構(gòu)建,也可以將這些邏輯納入編譯構(gòu)建腳本并部署到像 Jenkins 這樣現(xiàn)成的持續(xù)集成服務(wù)器上,總之,執(zhí)行完成后,打包好的 rpm 就發(fā)布到目標(biāo)環(huán)境對應(yīng)的 rpm 倉庫了。
rpm 包發(fā)布到 rpm 倉庫之后,就可以執(zhí)行部署,比如通過 Salt 或者 ansible 在目標(biāo)環(huán)境執(zhí)行 rpm 或者 yum 命令,但具體的部署行為可能因為不同開發(fā)者的習(xí)慣和理念而有所不同。
有的開發(fā)者喜歡將不同目標(biāo)環(huán)境的配置都一股腦地打包到發(fā)布包中,然后通過配置文件的命名和啟動程序時單獨指定一個環(huán)境變量來決定如何啟用哪一個配置文件,對于這種做法,只需要打一個 rpm 包,同時也只需要搭建一個內(nèi)部的 rpm 倉庫,部署的時候,則需要運維人員根據(jù)具體的操作環(huán)境傳遞相應(yīng)的環(huán)境變量來啟停程序。
有的開發(fā)者則認為,一個軟件實體發(fā)布的時候就應(yīng)該是針對目標(biāo)環(huán)境“裝配”完備的,rpm 包中的各項配置都是針對特定目標(biāo)環(huán)境配置好的,只要將 rpm 包部署到目標(biāo)環(huán)境,就可以直接啟動,啟停完全無差別操作,唯一的差別是,rpm 包分別是根據(jù)目標(biāo)環(huán)境發(fā)布和部署到不同的 rpm 倉庫的,如圖 3 所示。
圖 3 “根據(jù)不同交付目標(biāo)環(huán)境,設(shè)置不同RPM倉庫作為交付地點”示意圖
以上兩種策略并無優(yōu)劣之分,但卻有各自適合的場景:
1)在團隊小,以人為本的時候,前者更適合,原因在于,整個軟件交付鏈路更多是通過開發(fā)人員來協(xié)調(diào)和完成的。所以,開發(fā)、測試、運維一把抓,即使是不同環(huán)境的配置文件,也都是為了開發(fā)人員方便,直接放到了項目目錄下一起管理和修改。
當(dāng)?shù)搅司€上,開發(fā)人員同時擔(dān)當(dāng)運維人員的角色,啟停程序的可控性也很高,所以,可以在熟知自身程序的前提下,很好地完成整個鏈路的工作。
2)隨著團隊規(guī)模的擴張,職能更加明確,交付鏈路要承擔(dān)的關(guān)注點也更多的時候,為了保證整個軟件的交付質(zhì)量,需要引入規(guī)范化的流程來關(guān)聯(lián)和約束整個鏈路上各個環(huán)節(jié)和團隊之間的工作。
這個時候,開發(fā)人員的職責(zé)范圍將縮小到明確的范圍,測試團隊、安全團隊、應(yīng)用運維團隊等也將加入并根據(jù)流程各司其職,每個團隊之間的工作需要橫向關(guān)聯(lián)的同時,又需要垂直隔離。
這個時候,我們就需要從交付的源頭一直到發(fā)布和部署,根據(jù)環(huán)境進行隔離,每個人即使只關(guān)注自己負責(zé)的事情,也可以讓整個軟件交付鏈路很好地工作,這考慮的是規(guī)范和流程對整體粒度上的把控和支撐。
對于小團隊來說,微服務(wù)并不是什么太好的選擇,高內(nèi)聚的應(yīng)用開發(fā)和部署單元,對整個交付鏈路的要求沒那么高,也不需要更多自動化和平臺化層面的投入和支持。
而一旦你選擇了微服務(wù)的軟件交付策略,數(shù)量龐大的微服務(wù)治理將耗費更多資源在支撐整個交付鏈路的自動化和平臺化建設(shè)層面。否則,如此數(shù)量上的差異化的實體管理,單純還靠人工拼苦勞是“撈不著好果子吃的”。
所以,我們要標(biāo)準化和規(guī)范化微服務(wù)的開發(fā)、交付、部署以及運維,從而收斂整條鏈路的治理復(fù)雜度,以近乎無差別的方式,完成各個環(huán)節(jié)上的工作。這個時候,規(guī)范、流程、平臺是核心,對人的要求則適當(dāng)降低。
說了這么多,其實就一點,如果團隊要轉(zhuǎn)向微服務(wù)的交付策略,那么,標(biāo)準化、單一化的微服務(wù)發(fā)布和部署行為是大家努力的方向,雖然我們在說基于 RPM 這種特定的微服務(wù)發(fā)布和部署形式,但并不意味著我們只應(yīng)該關(guān)注這一點或者這單一環(huán)節(jié),只有系統(tǒng)的從整體的微服務(wù)交付鏈路和體系層面考慮,才能夠在各個單一環(huán)節(jié)落地的時候選擇合適的方案。
基于 RPM 的發(fā)布與部署方式就說這么多,希望對大家有所啟發(fā)。
基于 Docker 的發(fā)布與部署方式
隨著資源虛擬化技術(shù)的持續(xù)精進,一種基于容器(container)的方式開始風(fēng)行,Docker 就屬于當(dāng)下這個風(fēng)口上最耀眼的明星,而且,很多微服務(wù)相關(guān)的文章也是言必提 Docker,好像沒有 Docker 的微服務(wù)就不是正宗的微服務(wù)了,所以,我們自然也要適當(dāng)提及一下如何結(jié)合 Docker 發(fā)布和部署我們的 SpringBoot 微服務(wù)。
我們知道,RPM 包的構(gòu)建是使用系統(tǒng)的 rpmbuild 工具完成的,該工具需要一個構(gòu)建描述文件,即 .spec 文件,rpmbuild 工具讀取 .spec 構(gòu)建描述文件之后,根據(jù)構(gòu)建描述文件生成一個 rpm 包,然后我們就可以把 rpm 包發(fā)布到相應(yīng)的 RPM 倉庫(RPM Repository)。
使用 Docker 其實也是類似的過程,如圖 4 所示。
圖 4 基于Docker的SpringBoot微服務(wù)發(fā)布流程圖
我們需要提供一個 Dockerfile 用于描述 Docker 發(fā)布成品的構(gòu)建過程,這類似于 rpmbuild 需要的 .spec 文件。
在編寫好要使用的 Dockerfile 之后,我們使用 docker build 命令讀取 Dockerfile 開始構(gòu)建一個 Docker 的 image,docker build 完成 rpmbuild 類似的功能,Docker 的 image 則類似于 rpm 包,即 Docker 的軟件發(fā)布成品。
有了 docker image 之后,我們就可以將其發(fā)布到一個 Docker 的 image registry,這里的 image registry 就類似于 RPM 倉庫(RPM Repository),而將 docker image 發(fā)布到 image registry 的過程,可以通過 docker push 完成。
所以,假設(shè)要以 Docker 的形式發(fā)布我們的匯率查詢 SpringBoot 微服務(wù),首先需要編寫一個對應(yīng)的 Dockerfile 來構(gòu)建相應(yīng)的 docker image:
FROM java:8MAINTAINER AFOO <afoo@afoo.me>LABEL groupId=...LABEL artifactId=...LABEL version=...LABEL ...USER deployerEXPOSE 8080ENV {key}={value}...VOLUME ...RUN mkdir /{group}/{projectId}/configRUN mkdir /{group}/{projectId}/agentRUN mkdir /{group}/{projectId}/docsRUN mkdir /{group}/{projectId}/libCOPY target/docker-springboot-chapter4-0.0.1-SNAPSHOT.jar /{group}/{projectId}/lib/docker-springboot-chapter4-0.0.1-SNAPSHOT.jarCOPY conf/application.properties /{group}/{projectId}/config/application.propertiesCOPY agent/jolokia-jvm-1.3.3-agent.jar /{group}/{projectId}/jolokia-jvm-1.3.3-agent.jar...ENTRYPOINT ["java", "...", "-jar", "lib/docker-springboot-chapter4-0.0.1-SNAPSHOT.jar"]
之后,我們就可以使用這個 dockerfile 來進行構(gòu)建并發(fā)布了:
$ docker build . -t "{groupId}/{artifactId}:{version}
$ docker push 基于 Docker 的微服務(wù)部署與 RPM 類似,都是從發(fā)布倉庫中拉取發(fā)布的成品,并在目標(biāo)環(huán)境安裝部署,一般情況下我們也同樣是使用 Salt 或者 Ansible 之類的工具執(zhí)行如下類似的命令完成基于 Docker 的微服務(wù)的部署:
$ ansible {cluster} -m shell -a "cd /microservices/{groupId}/{artifactId}; docker pull"
為了簡化基于 Docker 的發(fā)布和部署流程,實際上,以上演示的只是單人單微服務(wù)項目的方法,在講究集團軍作戰(zhàn)的微服務(wù)場景下,我們希望的是能夠快速、批量且標(biāo)準化的形式完成數(shù)量巨大的微服務(wù)發(fā)布和部署。
這就要求不能只盯著單一項目內(nèi)部去思考如何實現(xiàn)發(fā)布和部署,而應(yīng)該將視線從單一項目內(nèi)部抽取出來,以更高的視角來審視如何快速地完成批量微服務(wù)的發(fā)布和部署。
筆者建議的一個思路是適當(dāng)?shù)厝趸?Docker 屬性,將發(fā)布和部署邏輯外部化到發(fā)布腳本中。
外部化后的發(fā)布腳本將集中協(xié)調(diào) Docker 基礎(chǔ)設(shè)施,要發(fā)布的微服務(wù)上下文信息以及其他中間步驟,將微服務(wù)項目與 Docker 掛鉤的唯一紐帶也僅僅是一個模板化、標(biāo)注化后的 Dockerfile,整個過程如圖 5 所示。
圖 5 外部化的基于Docker的SpringBoot微服務(wù)發(fā)布腳步邏輯流程圖
如此一來,對于所有希望以 Docker 形式發(fā)布的標(biāo)準化的微服務(wù)來說,一套發(fā)布腳本即可完成所有微服務(wù)的發(fā)布和部署,而不需要每一個微服務(wù)自己去編寫 Dockerfile 甚至發(fā)布腳本。
上面的 Docker 實踐并非 Docker 社區(qū)建議的最佳實踐方式,這里更多只是為了簡化說明和對比,Docker 背后是一套更為龐大完備的體系,比如 Docker 容器的注冊和發(fā)現(xiàn),容器的編排及調(diào)度等功能和系統(tǒng),限于篇幅和內(nèi)容定位,這里不再贅述。
總的來說,其實基于 Docker 的微服務(wù)發(fā)布和部署與其他形式從本質(zhì)上來說沒有太大差別,唯一的差別只是各自方案特定的實現(xiàn)不同而已。
大部分人選擇和認同 Docker 方案,更多是從系統(tǒng)資源利用率以及 Docker 對整個軟件交付鏈路的支撐體系比較完備這些角度考慮的,而微服務(wù)自身的很多特點以及需求(比如隔離、輕量),恰好與 Docker 能提供的相互吻合,或許這就是二者經(jīng)常被“相提并論”的原因。
不過,對于 Java 應(yīng)用和微服務(wù)來說,Docker 能給予的好處可能沒有想象的那么多。
到此這篇關(guān)于關(guān)于SpringBoot微服務(wù)發(fā)布與部署的三種方式的文章就介紹到這了,更多相關(guān)SpringBoot微服務(wù)發(fā)布與部署內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中ArrayList具體實現(xiàn)之簡單的洗牌算法
這篇文章主要給大家介紹了Java中ArrayList具體實現(xiàn)之簡單的洗牌算法,文中通過代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-12-12詳解Spring Cloud Finchley版中Consul多實例注冊的問題處理
這篇文章主要介紹了詳解Spring Cloud Finchley版中Consul多實例注冊的問題處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Sleuth(Micrometer)+ZipKin分布式鏈路問題小結(jié)
在微服務(wù)架構(gòu)中,分布式鏈路追蹤技術(shù)成為了解決系統(tǒng)復(fù)雜調(diào)用問題的關(guān)鍵,本文介紹了其他鏈路追蹤方案,如Cat、Pinpoint和Skywalking,展示了分布式鏈路追蹤技術(shù)的多樣化,感興趣的朋友一起看看吧2024-10-10Java判斷一個時間是否在當(dāng)前時間區(qū)間代碼示例
這篇文章主要給大家介紹了關(guān)于使用Java判斷一個時間是否在當(dāng)前時間區(qū)間的相關(guān)資料,在日常開發(fā)中我們經(jīng)常會涉及到時間的大小比較或者是判斷某個時間是否在某個時間段內(nèi),需要的朋友可以參考下2023-07-07