news 2026/8/12 18:04:10

Jenkins自动化部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jenkins自动化部署

一、介绍

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。
因为开发部门同时维护多个版本,多个版本的发布,测试需要大量人力,所以要有一个专业的持续集成工具来管理持续重复的工作。
个人理解,说白了就是把代码测试、打包、发布等工作交给一些工具来自动完成。这样可以提高效率,减少失误,开发人员只需要关心开发和提交代码到Git就可以了。

二、安装前资源准备(jenkins.war包、配套jdk、maven、离线插件、启动脚本等)

下载地址:https://download.csdn.net/download/weixin_39393393/93166322
资源详情:

三、安装部署

1、安装JDK

将JDK上传到指定目录并安装:

rpm-ivhjdk-17.0.2_linux-x64_bin.rpm

查看安装位置(Oracle JDK rpm 默认安装rpm安装位置:/usr/java/jdk-17.0.2)

配置环境变量

vim/etc/profile

最后追加:

exportJAVA_HOME=/usr/java/jdk-17.0.2exportPATH=$JAVA_HOME/bin:$PATHexportCLASSPATH=.:$JAVA_HOME/lib

让配置生效并验证:

source/etc/profile

2、安装maven

将Maven压缩包上传到指定目录并解压:


配置maven找到配置文件修改内容如下:

vimapache-maven-3.6.3/conf/settings.xml

修改仓库地址,指定自己的仓库目录:

<localRepository>/services/maven/repository</localRepository>

<mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf></mirror>


配置环境变量并检查

exportMAVEN_HOME=/services/maven/apache-maven-3.6.3exportPATH=$MAVEN_HOME/bin:$PATH

3、安装Jenkins并启动服务

将资源包中的 jenkins.war 包和启动脚本上传到指定目录:


修改启动脚本中的文件目录:

#!/bin/bash# 设置 JDK 路exportJAVA_HOME=/usr/java/jdk-17.0.2exportPATH=$JAVA_HOME/bin:$PATH# 设置 Jenkins 数据目录(任务、插件、配置等都会保存在这里)exportJENKINS_HOME=/services/jenkins/data# 启动 Jenkins,后台运行# -Djenkins.install.runSetupWizard=false 跳过安装向导# -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true 禁用 Jenkins 的 CSRF(Crumb)安全校验# -Dhudson.model.UpdateCenter.updateCenterUrl=file:///dev/null \ 禁止 Jenkins 检查插件和版本更新# -Dhudson.model.UpdateCenter.updateCenterUrl=https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/ 将 Jenkins 更新源修改为国内镜像(如清华镜像)nohup$JAVA_HOME/bin/java\-Djenkins.install.runSetupWizard=false\-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true\-jar/services/jenkins/jenkins.war\--prefix=/jenkins\--httpPort=8777\--httpListenAddress=0.0.0.0\>/services/jenkins/jenkins.log2>&1&

创建data目录并赋予权限,对jenkins-start.sh文件赋予执行权限

执行启动脚本,通过浏览器访问jenkins(端口号必须为8777)

http://你的IP地址:8777/jenkins

四、配置Jenkins

1、Jenkins中的插件(不在线下载可以使用上述的离线插件包)

将资源包中的plugins 覆盖 /services/jenkins/data/plugins 文件夹,并重启服务

可以看到中文插件已生效:

禁用插件升级:

2、Jenkins中全局工具配置,配置JDK、maven、git等


如果让Jenkins发布前端的话,需要配置nodejs:

3、Jenkins中全局安全配置

五、构建maven项目

1、新建任务并规划视图分组

任务视图分组:

将任务划分为该视图分组

2、任务配置

任务源码管理配置

添加全局凭证



添加完成后再 系统管理>凭据管理里可以看到


在前置步骤中使用maven命令构建程序包

clean package-DskipTests

前置步骤执行成功后可以在Jenkins 数据目录看到构建的项目工程target。

/services/jenkins/data/workspace 固定目录
services/jenkins/data/workspace/data-gateway 固定目录 + Jenkins任务名称
/services/jenkins/data/workspace/data-gateway/data-gateway 固定目录 + Jenkins任务名称 + 模块项目工程目录


在后置步骤中编写shell脚本让其执行:

2.1 、Jenkins发布脚本

下面附上脚本代码(根据个人使用情况修改关键参数即可)

由于jenkins构建消耗内存极大,一般jenkins是一台单独的工具机器,Java项目一般在其他的机器上,这里Jenkins服务部署在192.168.15.57虚拟服务器上,下面应用服务器192.168.15.58是java项目部署的虚拟服务器。
应用部署目录:指的是java项目应用程序部署的服务器jar包所在目录(包括启动脚本start和停止服务脚本stop都在该目录下)

应用服务器目录结构如下:


#!/bin/bash################################################ Jenkins发布脚本## 功能:# 1. 找到当前构建jar# 2. 上传应用服务器# 3. 备份旧jar# 4. 调用远程stop/start################################################ 应用服务器SERVER_IP="192.168.15.58"# SSH用户REMOTE_USER="root"# 应用部署目录APP_HOME="/services/app"# jar工程目录APP_NAME="data-gateway"# jar名称配置APP_JAR_NAME="data-gateway.jar"echo"JenkinsJob名称:"echo${JOB_NAME}echo"jar工程目录:"echo${APP_NAME}echo"jar名称:"echo${APP_JAR_NAME}#==========================# 查找jar ${WORKSPACE}包含${JOB_NAME}例如:/services/jenkins/data/workspace/${JOB_NAME}# ==========================JAR_FILE=$(find${WORKSPACE}/${APP_NAME}/target\-name"*.jar"\-not-path"*original*"\|head-1)if[!-f"${JAR_FILE}"];thenecho"没有找到jar"exit1fiecho"找到jar:"echo${JAR_FILE}#==========================# 上传#==========================echo"开始发布${APP_NAME}"ssh\-oStrictHostKeyChecking=no\${REMOTE_USER}@${SERVER_IP}<<EOF mkdir -p${APP_HOME}/${APP_NAME}/backup mkdir -p${APP_HOME}/${APP_NAME}/logs EOF#停止服务ssh\-oStrictHostKeyChecking=no\${REMOTE_USER}@${SERVER_IP}\"${APP_HOME}/${APP_NAME}/stop.sh"#==========================# 备份旧jar# <<EOF ... EOF 多行输入命令#==========================ssh\-oStrictHostKeyChecking=no\${REMOTE_USER}@${SERVER_IP}<<EOF if [ -f${APP_HOME}/${APP_NAME}/${APP_JAR_NAME}] then mv${APP_HOME}/${APP_NAME}/${APP_JAR_NAME}\${APP_HOME}/${APP_NAME}/backup/${APP_JAR_NAME}-$(date+%Y%m%d_%H%M%S)fi EOF#==========================# 上传新jar#==========================scp\-oStrictHostKeyChecking=no\${JAR_FILE}\${REMOTE_USER}@${SERVER_IP}:${APP_HOME}/${APP_NAME}/${APP_JAR_NAME}#==========================# 启动#==========================ssh\-oStrictHostKeyChecking=no\${REMOTE_USER}@${SERVER_IP}\"${APP_HOME}/${APP_NAME}/start.sh"echo"================================"echo"${APP_NAME}发布完成"echo"================================"

Jenkins发布脚本,是在192.168.15.57虚拟服务器上因为涉及到上传应用服务到java项目部署的虚拟服务器192.168.15.58上、还有备份、远程执行启停脚本等操作。所以这里先需要配置两台服务器的SSH免密登录

3、开启SSH免密登录

在192.168.15.57机器上使用root用户生成秘钥注意此处是root用户

$ ssh-keygen-trsa# 3次回车

运行后会在当前用户的根目录生成一个.ssh文件夹
.ssh文件夹中的文件描述(.ssh目录的权限必须是700)

  • id_rsa : 生成的私钥文件
  • id_rsa.pub : 生成的公钥文件

接下来需要将公钥导入到认证文件中

# .ssh/authorized_keys文件权限必须是600$cat~/.ssh/id_rsa.pub>>~/.ssh/authorized_keys

给对应文件授权

$chmod700~/.ssh $chmod600~/.ssh/authorized_keys

接下来将authorized_keys文件拷贝到另一台应用服务器的root用户.ssh目录下即可

scp-p~/.ssh/id_rsa.pub root@192.168.15.58:/root/.ssh/authorized_keys

最后在jenkins192.168.15.57服务器上进行免密连接测试

sshroot@192.168.15.58
3.1 、应用服务器上的start.sh启动脚本

start.sh 脚本内容如下:

#!/bin/bash############################################# Java服务启动脚本############################################JAVA_HOME=/www/server/java/jdk-17.0.8JAVA_BIN=${JAVA_HOME}/bin/java# 当前应用目录APP_HOME=$(cd$(dirname $0);pwd)# 日志文件(带启动时间)LOG_FILE=${APP_HOME}/logs/app-$(date"+%Y%m%d_%H%M%S").log# 判断jar数量是否为1JAR_COUNT=$(find${APP_HOME}-maxdepth1-name"*.jar"-typef|wc-l)if[${JAR_COUNT}-ne1];thenecho"错误: 当前目录jar数量异常:${JAR_COUNT}"exit1fi# 自动获取jar包全路径(只查当前目录下的jar包文件,只取第一个)JAR_FILE=$(find${APP_HOME}\-maxdepth1\-name"*.jar"\-typef\|head-1)# 日志目录LOG_DIR="${APP_HOME}/logs"mkdir-p${LOG_DIR}# JVM参数JAVA_OPTS=" -Xms512m -Xmx1024m "echo"================================"echo"启动服务"echo"目录:${APP_HOME}"echo"Jar路径:${JAR_FILE}"echo"日志:${LOG_DIR}"echo"================================"# 判断jar是否存在if[!-f"${JAR_FILE}"];thenecho"错误: jar不存在"echo"${JAR_FILE}"exit1fi# 启动 --spring.profiles.active=dev \ --config.nacos.server-addr=localhost:8848 \ --server.port=40009 \echo"启动命令:"echo"nohup${JAVA_BIN}${JAVA_OPTS}-jar${JAR_FILE}>${LOG_FILE}2>&1 &"nohup${JAVA_BIN}${JAVA_OPTS}\-jar${JAR_FILE}\>${LOG_FILE}2>&1&PID=$!echo"启动PID=${PID}"sleep20# 检查进程ifps-p${PID}>/dev/nullthenecho"Java进程存在"elseecho"启动失败"exit1fi
3.2 、应用服务器上的stop.sh停止脚本

stop.sh 脚本内容如下:

############################################# Java服务停止脚本# 功能:# 1. 根据jar名称查找Java进程# 2. 发送SIGTERM优雅停止# 3. 等待应用释放资源# 4. 超时后强制kill############################################# 当前应用目录APP_HOME=$(cd$(dirname $0);pwd)# 判断jar数量是否为1JAR_COUNT=$(find${APP_HOME}-maxdepth1-name"*.jar"-typef|wc-l)if[${JAR_COUNT}-ne1];thenecho"错误: 当前目录jar数量异常:${JAR_COUNT}"exit1fi# 自动获取jar包全路径(只查当前目录下的jar包文件,只取第一个)JAR_FILE=$(find${APP_HOME}\-maxdepth1\-name"*.jar"\-typef\|head-1)# 获取jar名称JAR_NAME=$(basename${JAR_FILE})echo"================================"echo"准备停止Java服务"echo"应用目录:${APP_HOME}"echo"Jar路径:${JAR_FILE}"echo"Jar名称:${JAR_NAME}"echo"================================"# 根据jar名称查询PIDPID=$(ps-ef\|grep"${JAR_NAME}"\|grep-vgrep\|awk'{print $2}')# 没有运行中的服务if[-z"${PID}"];thenecho"当前没有运行中的服务"exit0fiecho"发现运行PID:${PID}"echo"发送停止信号..."# 发送SIGTERM信号kill-15${PID}# 等待服务停止 最大等待30秒foriin{1..30}dosleep1PID_CHECK=$(ps-ef\|grep"${JAR_NAME}"\|grep-vgrep\|awk'{print $2}')# 没有运行中的服务if[-z"${PID_CHECK}"];thenecho"================================"echo"服务停止成功"echo"================================"exit0fiecho"等待服务关闭${i}s"done#===========================================# 超时强制关闭#===========================================echo"执行强制kill"kill-9${PID}echo"服务已强制停止"

4、一键构建发版

可以在控制台输出看到上述的脚本执行详细过程,如下图:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/12 18:00:00

Go 底层心智模型:并发、内存与闭包

写给已经能写 Go 但想知道"为什么"的人。这篇文章不讲语法&#xff0c;只聊机制。一、并发不是并行 很多人把这两个词当同义词用。Rob Pike 那句 “Concurrency is not parallelism” 被引用了无数遍&#xff0c;但真正能在白板上画清楚的人不多。 并发是程序的结构—…

作者头像 李华
网站建设 2026/8/12 17:57:28

从《开门大吉》到精准片段获取:视频定位、下载与处理全流程指南

1. 先搞清楚“开门大吉”这类节目片段的价值和获取难点如果你在找《开门大吉》这类综艺节目的片段&#xff0c;特别是像“站台”这样的经典歌曲表演环节&#xff0c;那你大概率不是想从头到尾看完整期节目。你更可能是想快速找到那个最精华的几分钟&#xff0c;用来做素材剪辑、…

作者头像 李华
网站建设 2026/8/12 17:57:15

AI工程技术进化:Loop Engineering

Loop Engineering&#xff1a;当你不再亲自提示 Agent&#xff0c;而是设计一套系统去提示它 引言&#xff1a;一句断言引发的范式讨论 2026 年 6 月&#xff0c;Peter Steinberger 发了一句被广泛转引的话&#xff1a;“你不该再亲自给编码 Agent 写提示词了。你应该设计一套能…

作者头像 李华
网站建设 2026/8/12 17:56:24

Rust与Java性能对比及迁移实践

1. 为什么Rust正在撼动Java的统治地位 最近在重构一个高并发中间件项目时&#xff0c;我同时用Java和Rust实现了核心模块。实测数据显示&#xff1a;Rust版本的内存占用只有Java的1/3&#xff0c;吞吐量却高出40%。这促使我深入对比了两者的技术特性&#xff0c;结果发现Java在…

作者头像 李华
网站建设 2026/8/12 17:53:14

元类(Metaclass)—— 站在“上帝视角”创造类的造物主

核心梗概&#xff1a;如果说类是模具&#xff0c;实例是模具造出的产品&#xff0c;那么元类就是制造模具的那台“机床”。今天带你当一回女娲&#xff0c;手搓泥人&#xff08;类&#xff09;。1. 惊不惊喜&#xff1f;类本身也是个“对象”很多初学 Python 的朋友会把“一切皆…

作者头像 李华