Maven antrun vs Jenkins 脚本组装 deb的优缺点、适用场景

发布时间:2026/10/7 20:14:34
Maven antrun vs Jenkins 脚本组装 deb的优缺点、适用场景 文章目录引言一、结论二、service 文件常见问题分析三、方案 AJenkins Pipeline 脚本组装 deb✅ 推荐核心思路项目目录结构deb/lib/systemd/system/sight-manage.service修正版deb/opt/sight/start.shexec 前台运行scripts/build-deb.shJenkins 调用Jenkinsfile 片段四、方案 Bmaven-antrun-plugin 组装 deb什么时候用pom.xml 配置antrun 方案的致命缺点五、两种方案对比总结六、最终推荐架构七、 service 文件的修正对照see alsoJenkins PipelineJenkinsfileFat-JAR胖JAR引言生产环境推荐使用 Jenkins Pipeline 脚本构建 deb 包相比 Maven Antrun 插件其可维护性、调试体验与 CI/CD 灵活性显著更优。方案核心为Maven 打包 fat-jarShell 脚本组装 deb 目录结构动态配置 JVM 内存并集成 systemd 服务管理。关键优化包括移除无效参数、拆分启动脚本、合理设置内存上限并通过 Jenkinsfile 实现自动化构建与上传至 APT 仓库确保部署高效可靠。一、结论维度maven-antrun-pluginJenkins Pipeline 脚本推荐度⭐⭐⭐⭐⭐⭐⭐复杂度高XML 里写 shell低直接 bash可维护性差XML 转义地狱好独立脚本文件调试体验差mvn 日志里翻好Jenkins 直接看与 deb 工具集成勉强原生CI/CD 灵活性低高本地也能打包✅❌依赖 CI 环境结论生产环境用 Jenkins 脚本方案。maven-antrun 只适合本地开发时快速验证 deb 结构。二、service 文件常见问题分析参数问题Userroot/Grouproot前面讨论过能用但不够安全ExecStart /usr/bin/java前面有空格systemd 会解析失败-XX:MaxNewSize640m-XX:SurvivorRatio16ZGC 下全部无效-XX:UseNUMARK3588 ARM 不是 NUMA-Xms2048m -Xmx2048m2GB 对 manage 服务偏多RK3588 总共 8GBExecStart一行太长不可维护改参数要改整个文件三、方案 AJenkins Pipeline 脚本组装 deb✅ 推荐核心思路Jenkinsfile → mvn package产出 fat-jar → bash scripts/build-deb.sh组装 deb 目录结构 → dpkg-deb --build → rsync 到 APT 仓库项目目录结构mes-manage/ ├── src/ │ ├── main/java/ │ └── resources/ │ └── application-prod.yml ├── deb/ │ ├── DEBIAN/ │ │ ├── control │ │ ├── postinst │ │ ├── prerm │ │ └── postrm │ ├── opt/ │ │ └── sight/ │ │ ├── start.sh │ │ └── conf/ │ │ └── application-prod.yml │ └── lib/ │ └── systemd/ │ └── system/ │ └── sight-manage.service ├── scripts/ │ └── build-deb.sh ├── pom.xml └── Jenkinsfiledeb/lib/systemd/system/sight-manage.service修正版[Unit] Descriptionsight Manage API (Spring Boot) Afternetwork.target mysql.service Wantsmysql.service [Service] Typesimple Usersight Groupsight WorkingDirectory/opt/sight # JVM 参数拆到 start.sh 里service 只管调脚本 ExecStart/opt/sight/start.sh ExecStop/bin/kill -SIGTERM $MAINPID TimeoutStopSec30 Restartalways RestartSec5 StandardOutputjournal StandardErrorjournal SyslogIdentifiersight-manage PrivateTmptrue ProtectSystemstrict ReadWritePaths/opt/sight/logs /var/log/sight /var/lib/sight [Install] WantedBymulti-user.targetdeb/opt/sight/start.shexec 前台运行#!/bin/bash# sight-manage start script# 注意不用 nohup不用 用 exec 让 systemd 管控 javaset-eJAR/opt/sight/sight-manage.jarJAVA/usr/bin/javaif[!-x${JAVA}];thenechoERROR: java not found at${JAVA}2exit1fiif[!-f${JAR}];thenechoERROR:${JAR}not found2exit1fi# 动态内存物理内存的 1/4上限 2048mMEM_KB$(grepMemTotal /proc/meminfo|awk{print $2})HEAP_MB$((MEM_KB/1024/4))[${HEAP_MB}-gt2048]HEAP_MB2048[${HEAP_MB}-lt512]HEAP_MB512# exec用 java 替换当前 shell 进程exec${JAVA}\-Xms${HEAP_MB}m\-Xmx${HEAP_MB}m\-XX:UseZGC\-XX:HeapDumpOnOutOfMemoryError\-XX:HeapDumpPath/var/log/sight/heapdump.hprof\-Duser.timezoneGMT08\-Dfile.encodingUTF-8\-Dspring.profiles.activeprod\-Dspring.config.locationfile:/opt/sight/conf/application-prod.yml\-jar${JAR}scripts/build-deb.shJenkins 调用#!/bin/bashset-eVERSION${1:-$(mvn help:evaluate -Dexpressionproject.version -q -DforceStdout)}BUILD_DIRbuild/deb/sight-manage_${VERSION}_allecho Building deb v${VERSION}# 清理 创建目录rm-rfbuild/debmkdir-p${BUILD_DIR}/DEBIANmkdir-p${BUILD_DIR}/opt/sight/confmkdir-p${BUILD_DIR}/opt/sight/logsmkdir-p${BUILD_DIR}/lib/systemd/system# 1. 复制 jarcptarget/sight-manage.jar${BUILD_DIR}/opt/sight/# 2. 复制配置文件cpdeb/opt/sight/conf/application-prod.yml${BUILD_DIR}/opt/sight/conf/cpdeb/opt/sight/start.sh${BUILD_DIR}/opt/sight/chmodx${BUILD_DIR}/opt/sight/start.sh# 3. 复制 systemd servicecpdeb/lib/systemd/system/sight-manage.service${BUILD_DIR}/lib/systemd/system/# 4. 复制 DEBIAN 控制文件cpdeb/DEBIAN/control${BUILD_DIR}/DEBIAN/cpdeb/DEBIAN/postinst${BUILD_DIR}/DEBIAN/cpdeb/DEBIAN/prerm${BUILD_DIR}/DEBIAN/cpdeb/DEBIAN/postrm${BUILD_DIR}/DEBIAN/# 替换版本号sed-is/^Version:.*/Version:${VERSION}/${BUILD_DIR}/DEBIAN/control# 设置脚本权限chmod755${BUILD_DIR}/DEBIAN/postinstchmod755${BUILD_DIR}/DEBIAN/prermchmod755${BUILD_DIR}/DEBIAN/postrm# 打包dpkg-deb--build--root-owner-group${BUILD_DIR}echo Done: sight-manage_${VERSION}_all.deb ls-lhsight-manage_${VERSION}_all.debJenkinsfile片段stage(Build Fat-Jar){steps{shmvn clean package -DskipTests}}stage(Assemble DEB){steps{shbash scripts/build-deb.sh}}stage(Verify DEB){steps{sh dpkg-deb -I sight-manage_*_all.deb dpkg-deb -c sight-manage_*_all.deb | head -20 }}stage(Upload to APT Repo){steps{sshagent(credentials:[apt-repo-rsync]){sh VERSION$(dpkg-deb -f sight-manage_*_all.deb Version) rsync -avz sight-manage_${VERSION}_all.deb \ aptly192.168.20.100:/srv/incoming/ ssh aptly192.168.20.100 \ aptly repo add mes-stable /srv/incoming/sight-manage_${VERSION}_all.deb \ aptly publish switch stable mes-stable-$(date %Y%m%d-%H%M%S) }}}四、方案 Bmaven-antrun-plugin 组装 deb什么时候用本地开发想mvn package直接出 deb没有 Jenkins 环境快速验证 deb 结构pom.xml配置buildfinalNamesight-manage/finalNameplugins!-- Spring Boot --plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexecutabletrue/executable/configuration/plugin!-- 复制 deb 资源 --pluginartifactIdmaven-resources-plugin/artifactIdversion3.3.1/versionexecutionsexecutionidcopy-deb-resources/idphasepackage/phasegoalsgoalcopy-resources/goal/goalsconfigurationoutputDirectory${project.build.directory}/deb-build/outputDirectoryresourcesresourcedirectorydeb/directoryfilteringfalse/filtering/resource/resources/configuration/execution/executions/plugin!-- antrun: 组装 deb 目录 dpkg-deb 打包 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-antrun-plugin/artifactIdversion3.1.0/versionexecutionsexecutionidbuild-deb/idphasepackage/phasegoalsgoalrun/goal/goalsconfigurationtarget!-- 创建目录结构 --mkdirdir${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIAN/mkdirdir${project.build.directory}/deb-build/sight-manage_${project.version}_all/opt/sight/conf/mkdirdir${project.build.directory}/deb-build/sight-manage_${project.version}_all/opt/sight/logs/mkdirdir${project.build.directory}/deb-build/sight-manage_${project.version}_all/lib/systemd/system/!-- 复制 jar --copyfile${project.build.directory}/sight-manage.jartofile${project.build.directory}/deb-build/sight-manage_${project.version}_all/opt/sight/sight-manage.jar/!-- 复制 service 文件 --copyfiledeb/lib/systemd/system/sight-manage.servicetodir${project.build.directory}/deb-build/sight-manage_${project.version}_all/lib/systemd/system//!-- 复制 start.sh --copyfiledeb/opt/sight/start.shtofile${project.build.directory}/deb-build/sight-manage_${project.version}_all/opt/sight/start.sh/chmodfile${project.build.directory}/deb-build/sight-manage_${project.version}_all/opt/sight/start.shperm755/!-- 复制 DEBIAN 脚本 --copyfiledeb/DEBIAN/postinsttodir${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIAN//copyfiledeb/DEBIAN/prermtodir${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIAN//copyfiledeb/DEBIAN/postrmtodir${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIAN//!-- 生成 control 文件替换版本号 --copyfiledeb/DEBIAN/controltofile${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIAN/control/!-- 设置权限 --chmodperm755filesetdir${project.build.directory}/deb-build/sight-manage_${project.version}_all/DEBIANincludenamepostinst/includenameprerm/includenamepostrm//fileset/chmod!-- 执行 dpkg-deb 打包 --execexecutabledpkg-debfailonerrortrueargvalue--build/argvalue--root-owner-group/argvalue${project.build.directory}/deb-build/sight-manage_${project.version}_all/argvalue${project.build.directory}/sight-manage_${project.version}_all.deb//execechomessageDEB package created: ${project.build.directory}/sight-manage_${project.version}_all.deb//target/configuration/execution/executions/plugin/plugins/buildantrun 方案的致命缺点问题说明XML 里写 shell要转义为lt;要转义为amp;调试困难mvn 日志混在一起看不到中间状态条件逻辑弱想判断架构、判断文件存在ant 条件语法反人类不可复用这段 XML 绑死在 pom 里Jenkins 没法单独调打包工具耦合dpkg-deb 必须在本地有Windows 开发机直接挂版本管理control 文件版本号替换要用 filter容易出错五、两种方案对比总结维度Jenkins 脚本maven-antrun学习成本低bash 谁都会高ant XML 语法可调试✅bash -x❌ mvn 日志翻可复用✅ 脚本可独立运行❌ 绑死 Maven跨平台❌ 依赖 Linux❌ 依赖 dpkg-debCI 集成✅ 原生⚠️ 能跑但不优雅适合生产✅❌适合本地验证⚠️ 要装 dpkg-deb✅mvn package一条命令六、最终推荐架构开发阶段mvn package → 本地手动 dpkg-deb -b 验证结构 CI 阶段Jenkins → build-deb.sh → dpkg-deb → APT 仓库 生产部署终端 apt update apt install sight-managemaven-antrun 不要用在 CI 里它的定位是本地开发时mvn package顺带出个 deb 方便联调不是生产打包方案。七、 service 文件的修正对照原来修正后原因UserrootUsersight最小权限ExecStart /usr/bin/java前有空格去掉空格systemd 解析JVM 参数全堆 ExecStart 一行拆到start.sh可维护-XX:MaxNewSize-XX:SurvivorRatio删除ZGC 无效-XX:UseNUMA删除ARM 无效-Xms2048m -Xmx2048m动态计算适配不同硬件start.sh用 nohup exec javasystemd 管控see alsoJenkins Pipeline是Jenkins 2.x版本引入的核心持续交付功能通过Jenkinsfile将构建、测试、部署等流程编码为可版本控制的脚本实现流水线即代码。相比传统自由风格任务它具备版本可追溯、多分支隔离、失败可重入等优势适用于微服务并行构建、多环境部署等复杂场景。Jenkins Pipeline分为声明式结构化、易维护和脚本式灵活但需掌握Groovy两种语法生产中推荐优先使用声明式。其关键特性包括通过agent配置动态分配执行节点如Docker容器或Kubernetes Pod、使用共享库复用逻辑、集成凭据管理实现安全构建。典型应用包括多阶段CI/CD流程自动化如代码检出、并行测试、镜像构建及部署。Jenkinsfile是 Jenkins 流水线的代码化配置文件使用 Groovy 语法定义 CI/CD 流程支持声明式和脚本式两种写法。它将构建、测试、部署等步骤以代码形式管理可提交到版本控制系统如 Git实现版本化和团队协作。典型结构包含 agent执行节点、stages阶段、steps步骤等元素可配置环境变量、条件分支、循环等复杂逻辑。在生产环境中Jenkinsfile 通过Pipeline 插件实现自动化构建相比 Maven Antrun 等方案具有更高的可维护性和灵活性尤其适合动态编排复杂流水线任务。Fat-JAR胖JAR是一种包含项目所有依赖的可执行JAR文件通过Maven插件如Assembly或Shade将主类和依赖打包到一个文件中适合独立部署。Spring Boot默认使用嵌套结构的Fat-JAR依赖存放在BOOT-INF/lib目录通过自定义类加载器解决类路径问题。Maven配置示例使用Assembly插件指定主类mainClasscom.example.MainClass/mainClass执行mvn package生成带依赖的JAR。其优势是部署简单但需注意依赖冲突和文件体积。