Spring Boot 2.3.0發佈:聚焦雲技術

Spring Boot發佈了2.3.0版本,添加了對buildpacks方式的Docker、分層鏡像、優雅關機、存活性(liveness)和就緒性(readiness)探針的支持。另外一個值得關注的變化就是它支持Java 14,同時保持了對Java LTS版本8和11的支持。

Buildpacks是Dockerfiles的一個替代方案。Buildpacks能夠自動探測運行Docker容器中的應用時所需要的軟件。例如,它會探測應用中所使用的Java版本。基於該版本,buildpack會選擇所指定的JRE並構建Docker鏡像。藉助Maven或Gradle,可以通過如下的命令創建Docker鏡像:

spring-boot:build-image

注意,創建基於buildpacks的Docker鏡像不需要任何配置。

通過使用bootBuildImage task,我們可以修改buildpack的一些配置。例如,構建文件中如下的Spring Boot Maven Plugin配置展示瞭如何修改Docker鏡像的名稱:

<configuration>
    <image>
        <name>infoq.com/${project.artifactId}:${project.version}</name>
    </image>
</configuration>

我們還可以通過命令行來指定Docker鏡像的名稱:

mvn/gradle bootBuildImage --imageName=infoq.com/my-app:v1

Docker鏡像是以分層的形式運行的。添加應用程序製件(artifact)作爲最新的層有助於減少鏡像所佔用的磁盤大小。開發人員經常將應用程序製件保存爲JAR文件。JAR文件的缺點在於它包含了經常發生變化的元素,比如代碼。但是,JAR文件還也包含了不經常發生變化的元素,比如依賴項。Docker鏡像版本的變更是以diffs的形式進行存儲的。當應用程序的每個版本以JAR文件的方式來進行存儲的時候,diff就會非常大,因此會消費很多的磁盤空間。Buildpacks基於變化更頻繁的元素,將應用切分爲多個分層從減少了空間的佔用。

將製件切分爲多個分層的功能也能用在Dockerfile中。Buildpacks提供了某種形式的配置,但是Dockerfiles能夠對最終形成的鏡像提供完全的控制。因此,開發人員有時更喜歡Dockerfile,而不是buildpack。當選擇使用Dockerfile的時候,建議將製件切分爲多個層。相對於buildpack,這需要更多一點的工作,但這是個一次性的任務。

首先,配置spring-boot-maven-plugin生成分層的JAR:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <layers>
                    <enabled>true</enabled>
                </layers>
            </configuration>
        </plugin>
    </plugins>
</build>

這個插件配置會確保應用會分爲四部分:依賴項、spring-boot-loader、快照依賴(snapshot-dependencies)和應用程序。

如下的程序片段展示了一個多階段的Dockerfile。在第一步中,應用是按照特定的jarmode參數運行的。這會讓四個組成部分各自存放到自己的目錄中。在下一個階段,這四個目錄會複製到Docker鏡像獨立的分層中,隨後指定了入口點。

FROM adoptopenjdk:14-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
 
FROM adoptopenjdk:14-jre-hotspot
WORKDIR application
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"]

開發人員可以使用Dockerfile構建Docker鏡像,隨後就能夠基於鏡像運行一個容器了:

docker build . --tag infoqdocker run -p8080:8080 infoq

像Kubernetes這樣的容器系統會用到存活性和就緒性探針。Kubernetes在爲應用生成新版本的時候,會啓動一個新的pod。這個新pod在啓動時,會和運行舊版本應用程序的舊pod同時存在。當新pod就緒的時候,它會接收流量,舊的pod會被移除掉。但是,當容器就緒的時候,應用通常並沒有完全啓動起來。這是因爲Spring Boot會耗費幾秒鐘的時間。默認情況下,這意味着舊版本的應用在關閉的時候,尚未完全啓動的應用已經在接收流量了。

這可以通過輪詢應用內特定的URL來解決,該URL在應用程序啓動後纔可用。只要URL可用,應用就準備好接收流量了,舊版本則可以刪除了。在Kubernetes中,這可以通過所謂的ReadinessProbe來實現。

Spring Boot現在提供了就緒性探針的默認支持。例如,在應用程序的配置中,啓用該功能後,就可以通過http://localhost:8080/actuator/health/readiness端點使用該探針了,啓用方式是如下的配置:management.health.probes.enabled=true。

除了ReadinessProbe之外,Kubernetes還有一個存活性的概念。它會按照預先定義的間隔驗證應用程序的功能是否正常。如果應用沒有響應的話,pod將會重啓。Spring Boot也爲此提供了一個端點:http://localhost:8080/actuator/health/liveness。

這些不同的端點是內置支持的,但是可以對它們進行配置,比如等待數據庫啓動完成。

優雅關機用來在停止應用之後,系統會爲正在進行中的請求維持一定的時間。

如下的代碼片段展示瞭如何啓用優雅關機並將超時時間設置爲30秒:

server.shutdown=gracefulspring.lifecycle.timeout-per-shutdown-phase=30s

這意味在停止應用後,不允許接收新的請求。但是,在應用徹底停止之前,舊的請求依然還有30秒的時間來等待其完成。

原文鏈接:
Spring Boot 2.3.0 Focuses on the Cloud

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章