SpringBoot项目分离与分层方式之容器化部署

1.前言

之前也分享过分离与分层方式部署,本文只不过将之前的那两种方式放到了容器中来部署运行,里面多多少少还是有点坑在里面的,要对简单一点直接使用如下命令部署:

nohup java -jar xxxx.jar --spring.profiles.active=xx ,,,,, > xxxx.log &

使用容器部署方式就比这种更高级优雅一点,根据个人喜好去选择适合自己的部署方式。

之前的文章链接如下:

https://blog.csdn.net/qq_34905631/article/details/126616809?spm=1001.2014.3001.5501https://mp.weixin.qq.com/s/OTZ-VVn_VimHNcSdEaLYJwhttps://blog.csdn.net/qq_34905631/article/details/126574085?spm=1001.2014.3001.5501https://mp.weixin.qq.com/s/5mhF1ge_yYUA6tMCYi77Og

2.deom项目工程结构


3.分离容器部署

3.1父工程pom

这里只展示build的配置

<build>                <plugins>                                                <plugin>                <groupId>org.springframework.bootgroupId>                <artifactId>spring-boot-maven-pluginartifactId>                <version>2.3.12.RELEASEversion>                <configuration>                                        <mainClass>xxxx.xxxx.xxxx.xxxApplicationmainClass>                                        <jvmArguments>-Dfile.encoding=UTF-8jvmArguments>                                        <includeSystemScope>trueincludeSystemScope>                    <layout>ZIPlayout>                    <classifier>execclassifier>                    <addResources>trueaddResources>                    <fork>truefork>                                                            <outputDirectory>${project.build.directory}outputDirectory>                    <skip>trueskip>                    <includes>                                                                                                <include>                            <groupId>non-existsgroupId>                            <artifactId>non-existsartifactId>                        include>                                                                    includes>                configuration>                <executions>                    <execution>                        <goals>                            <goal>repackagegoal>                        goals>                    execution>                executions>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-resources-pluginartifactId>                <version>3.2.0version>                <executions>                    <execution>                        <id>copy-resourcesid>                        <phase>packagephase>                        <goals>                            <goal>copy-resourcesgoal>                        goals>                        <configuration>                            <resources>                                <resource>                                    <directory>src/main/resourcesdirectory>                                    <excludes>                                        <exclude>static/**exclude>                                        <exclude>*.xmlexclude>                                                                                <exclude>*.ymlexclude>                                    excludes>                                resource>                            resources>                            <outputDirectory>${project.build.directory}/resourcesoutputDirectory>                        configuration>                    execution>                executions>                <configuration>                    <nonFilteredFileExtensions>                        <nonFilteredFileExtension>pemnonFilteredFileExtension>                    nonFilteredFileExtensions>                configuration>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-javadoc-pluginartifactId>                <version>2.9version>                <configuration>                    <attach>trueattach>                                        <charset>UTF-8charset>                                        <encoding>UTF-8encoding>                                        <docencoding>UTF-8docencoding>                configuration>                <executions>                    <execution>                        <id>attach-javadocsid>                        <goals>                            <goal>jargoal>                        goals>                        <configuration>                            <additionalparam>-Xdoclint:noneadditionalparam>                        configuration>                    execution>                executions>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-source-pluginartifactId>                <version>3.2.1version>                <executions>                    <execution>                        <id>attach-sourcesid>                        <goals>                            <goal>jargoal>                        goals>                    execution>                executions>            plugin>            <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-jar-pluginartifactId>                <version>3.3.0version>                <configuration>                                        <excludes>                                                <exclude>*.propertiesexclude>                                                <exclude>*.jsonexclude>                                                                       <exclude>*.pngexclude>                        <exclude>*.txtexclude>                    excludes>                    <archive>                                                <addMavenDescriptor>falseaddMavenDescriptor>                        <manifest>                                                        <mainClass>xxx.xxxxx.xxxiApplicationmainClass>                                                        <useUniqueVersions>falseuseUniqueVersions>                                                        <addClasspath>trueaddClasspath>                                                        <classpathPrefix>lib/classpathPrefix>                                                    manifest>                        <manifestEntries>                                                        <Class-Path>./resources/Class-Path>                                                        <Class-Path>lib/xxxxxx.xxxxx.jar lib/xxxxxx.xxxx.jar Class-Path>                        manifestEntries>                    archive>                    <outputDirectory>${project.build.directory}outputDirectory>                configuration>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-dependency-pluginartifactId>                <version>3.6.0version>                <executions>                    <execution>                        <id>copy-dependenciesid>                        <phase>packagephase>                        <goals>                            <goal>copy-dependenciesgoal>                        goals>                        <configuration>                                                        <type>jartype>                            <includeTypes>jarincludeTypes>                                                        <outputDirectory>                                ${project.build.directory}/lib                            outputDirectory>                        configuration>                    execution>                executions>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-deploy-pluginartifactId>                <version>2.8.2version>                <configuration>                    <skip>trueskip>                configuration>            plugin>                    plugins>        <finalName>${project.artifactId}finalName>    build>

3.2子模块3的Dockerfile

FROM xxx基础镜像VOLUME /resourcesWORKDIR /appADD target/xxx.jar /app/app.jarADD target/lib /app/lib/ADD target/resources/* /app/resources/# COPY target/resources/*.yml /app/config/ 这种方式是将boostrap.yml文件拷贝到config,提升了加载优先级别,否则找不到这个ymlRUN echo "Asia/Shanghai" > /etc/timezoneEXPOSE xxx对外暴露监听端口ENTRYPOINT java ${JAVA_OPTS} ${JAVA_PARAMETERS} ${SERVER_NAME}  -Xss1m -jar /app/app.jar
容器中工作路径下有app.jar、config。resources这几项.

3.3子模块3的target

子模块3打包之后target下文件如图所示:


3.4构建启动docker命令

#进入到子模块三路劲中docker build -t xx:v2.0.0 .docker run -itd -p xxx:xxx --ip=本机ip(连接wifi的ip) -e JAVA_OPTS="-Xms200m -Xmx200m -Xss256K -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=jvm远程调试监听端口 -Dfile.encoding=UTF-8" --name xxx-xxxx-server xx:v2.0.0

4.分层容器部署

4.1父工程pom

这里只展示build的配置

<build>                <plugins>                                                <plugin>                <groupId>org.springframework.bootgroupId>                <artifactId>spring-boot-maven-pluginartifactId>                <version>2.3.12.RELEASEversion>                <configuration>                    <mainClass>xxxlx.xxxx.xxxApplicationmainClass>                    <includeSystemScope>trueincludeSystemScope>                                                            <layers>                        <enabled>trueenabled>                    layers>                                    configuration>                <executions>                    <execution>                        <goals>                            <goal>repackagegoal>                        goals>                    execution>                executions>            plugin>                                                <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-javadoc-pluginartifactId>                <version>2.9version>                <configuration>                    <attach>trueattach>                                        <charset>UTF-8charset>                                        <encoding>UTF-8encoding>                                        <docencoding>UTF-8docencoding>                configuration>                <executions>                    <execution>                        <id>attach-javadocsid>                        <goals>                            <goal>jargoal>                        goals>                        <configuration>                            <additionalparam>-Xdoclint:noneadditionalparam>                        configuration>                    execution>                executions>            plugin>                        <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-source-pluginartifactId>                <version>3.2.1version>                <executions>                    <execution>                        <id>attach-sourcesid>                        <goals>                            <goal>jargoal>                        goals>                    execution>                executions>            plugin>                                    <plugin>                <groupId>org.apache.maven.pluginsgroupId>                <artifactId>maven-deploy-pluginartifactId>                <version>2.8.2version>                <configuration>                    <skip>trueskip>                configuration>            plugin>                    plugins>        <finalName>${project.artifactId}finalName>    build>

这个是用之前的分离打包的build改的,测试是ok的


4.2子模块3的Dockerfile

FROM xxxx基础镜像 AS builderVOLUME /resourcesWORKDIR /app# 配置参数ARG JAR_FILE=target/xxxx.jar# 将编译构建得到的jar文件复制到镜像空间中COPY ${JAR_FILE} /app/app.jar#ADD target/lib /app/lib/#ADD target/resources/* /app/resources/# COPY target/resources/*.yml /app/config/# 通过工具spring-boot-jarmode-layertools从application.jar中提取拆分后的构建结果RUN java -Djarmode=layertools -jar app.jar extractRUN echo "Asia/Shanghai" > /etc/timezone# 正式构建镜像FROM xxxx基础镜像WORKDIR /app# 前一阶段从jar中提取除了多个文件,这里分别执行COPY命令复制到镜像空间中,每次COPY都是一个layerCOPY --from=builder /app/dependencies/ ./COPY --from=builder /app/spring-boot-loader/ ./COPY --from=builder /app/snapshot-dependencies/ ./COPY --from=builder /app/application/ ./
EXPOSE xxx对外暴露监听端口ENTRYPOINT ["java","-Xms200m","-Xmx200m","-Xss256K","-Xdebug", "-Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=xxxxjvm远程调试监听端口", "-Dfile.encoding=UTF-8", "org.springframework.boot.loader.JarLauncher"]

这种方式是用一个胖jar包来提取分层镜像构建的,缺点是不能动态传递启动参数,必须在ENTRYPOINT中写死。


4.3子模块3的target

这种方式是一个正常的java胖jar包,所有的都打入到这个胖jar中,这里就不展示了。


4.4构建启动docker命令

#进入到子模块三路劲中docker build -t xx:v2.0.0 .docker run -itd -p xxx:xxxx --ip=本机ip(wifi连接的ip) --name lq-invoice-server xx:v2.0.0

5.jekines脚本

pipeline {    agent any	environment {	    image_tag="xxxxx/xxxxx/xxxxxx:v1.0.${BUILD_NUMBER}"	    git_address="http://xxxx/xxxx/xx.git"	    git_branch="xxx"	    port=xxxxx	    git_auth="xxxxxx"	    registry_name="xxxxx"        registry_pwd="xxxx"        container_name="xxxxxxxx"        JAVA_OPTS="-javaagent:/agent/skywalking-agent.jar -Dskywalking.agent.service_name=[xxxx-xxxx-xxx] -Dskywalking.trace.ignore_path=/actuator/** -Xms512m -Xmx512m -Xss256K -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=xxxxxx"	}	stages {	    stage("拉取代码") {	        steps {	            git branch: "${git_branch}", credentialsId: "${git_auth}",url: "${git_address}"	        }	    }	    stage('质量扫描') {	        steps {	            echo '跳过扫描'	        }	    }	    stage('maven编译') {	        steps {	            sh 'mvn -B -f ./pom.xml clean install -DskipTests'	        }	    }	    stage('编译镜像') {	        steps {	            sh '''	            cd 子模块三路劲/	            cp target/*.jar ./	            docker build -t ${image_tag} .	            '''	            sh 'docker login --username=${registry_name} --password=${registry_pwd} xxxx.xxxx.xxxx私服域名'	            sh 'docker push ${image_tag}'	            sh 'docker rmi ${image_tag}'	        }	    }	    stage('部署服务') {            steps {                echo '自动部署'                sh '''                ssh root@服务器ip << remotessh                docker stop ${container_name}                docker rm ${container_name}                docker pull ${image_tag}                docker run -d -p ${port}:${port} --net=host -e SERVER_PORT=${port} -e JAVA_OPTS="${JAVA_OPTS}" --name ${container_name} ${image_tag}                exit                remotessh                '''            }        }	}}

这个构建分离的是没有啥问题的,构建分层的这个docker run 需要修改一下,参数不能动态传了,直接修改为4.4构建启动docker命令的docker run命令部署即可。


6.总结

这两种方式是之前分享之后的酝酿灵感思路融合实践总结,上面两种方式是互斥的,任选一种即可,希望我的分享对你有所启发和帮助,请一键三连,么么么哒!

请使用浏览器的分享功能分享到微信等