天天看點

加快 java 項目 Docker 鏡像建構速度的野路子

最近接手了一個 java 項目,無論是測試環境還是正式環境,都是 CI/CD 系統自動建構和部署的,用的 Docker,被 java 項目的建構速度虐到了。

無論是 Python、Node.js、Go,從零打包鏡像的話,在有 Docker cache 的情況下,連續建構鏡像的速度是可以很快的。一般的優化方式是先安裝依賴子產品,然後再編譯打包代碼庫。這樣安裝依賴的 image layer 可以被 Docker 緩存,下次再建構就不用安裝依賴。

Java 項目也可以進行類似的優化,比如在 Dockerfile 當中先執行 mvn dependency:resolve 。可但是... 在 mvn 打包的時候,還是莫名奇妙的要下載下傳一些 maven 包下來,這導緻鏡像的建構速度依然很慢。

不是很了解 maven 包管理的機制,但是和 npm、pip 相比,不得不說太繁瑣了。。。這門語言都很繁瑣了。。。無奈之下,想了個野路子。

本地使用 maven 打包是很快的,因為需要的

QQ号碼買号平台

已經下載下傳下來了,Docker 建構鏡像慢,說到底是因為 CI/CD 系統中沒有下載下傳好子產品檔案。既然 Docker cache 不能幫我們解決這個問題,那我們就用 base image 來解決。

具體方法是在代碼庫裡面新寫一個 Dockerfile,就叫它 Dockerfile.light 好了,内容大概是下面這樣的:

FROM maven:3.5-jdk-8

WORKDIR /src

COPY ./pom.xml /src

RUN mvn dependency:resolve

COPY ./demo /src/src/main/java/hello/

RUN mvn package -Dmaven.test.skip=true

這個 Dockerfile.light 裡,将 pom.xml 放進去,但是項目代碼不放進去,把 spring boot 的 Get Started 代碼放進去,然後使用 maven 打包。

原 Dockerfile 中,将 base image 修改成 Dockerfile.light 建構出來的鏡像。然後去掉 mvn dependency:resolve 的那部分代碼,直接使用 maven 打包:

-FROM maven:3.5-jdk-8

+FROM baseImage:latest

-WORKDIR /src

-COPY ./pom.xml /src

-RUN mvn dependency:resolve

+RUN rm -rf ./src/main/java/hello

COPY . /src

RUN mvn package -Dmaven.test.skip=true

RUN cp target/*.jar app.jar

CMD java -jar app.jar

如此一來,這個項目每次将建立兩個鏡像,baseImage 鏡像的版本其實并不太重要,隻要在建構的時候能夠下載下傳到就行,畢竟項目的 pom.xml 還是比較穩定的,不會變動太大,就算變了使用 baseImage 依然能夠幫我們減少打包時下載下傳子產品的時間。

實際項目測試,如果不修改 pom.xml ,項目建構的時間至少縮短了 50%。當然,這種方案比較适合使用 CI/CD 時使用,因為打包的操作都是自動觸發的,不需要手動一個一個建構,項目多産生一個鏡像也不會增加什麼負擔。