侧边栏壁纸
博主头像
术业有道之编程博主等级

亦是三月纷飞雨,亦是人间惊鸿客。亦是秋霜去叶多,亦是风华正当时。

  • 累计撰写 99 篇文章
  • 累计创建 50 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

使用jenkins构建java项目

Administrator
2021-01-08 / 0 评论 / 0 点赞 / 193 阅读 / 13257 字

写在前面

这是一个在Jenkins下使用shell脚本发布一个java项目的过程,其中打包好的jar是直接跑在运行服务器上的,下次有空可以写一个docker方式的(当然也有必要探讨一下jar有没有必要在docker中运行)

一、在Jenkins项目中增加参数化构建

之所以有这么多详细参数是为了更加灵活的定制化,来适应运行服务器的各种情况

结构说明:

  • 变量名
    • 变量默认值
    • 变量说明

详细的参数:

  • branch

    • master
    • 要操作的分支
  • projectName

    • test-milk
    • 项目名(磁盘上的文件夹)
  • jenkinsProjectName

    • test-milk
    • jenkins项目名(jenkins工作空间的文件夹)
  • mavenCmd

    • clean package install -DskipTests --settings ${JENKINS_HOME}/workspace/deployment-init/aliyun/jenkins/settings.xml
    • maven 的运行命令
  • jarName

    • a-crawler-w-0.0.1-SNAPSHOT.jar
    • jar包名称
  • runServer

    • root@xxx.xxx.xxx.xxx
    • jar运行的目标服务器
  • shellDeployment

    • /root/shell-deployment
    • runServer 服务器的脚本根路径
  • javaHome

    • /usr/java/jdk1.8.0_111
    • runServer 服务器的jdk javahome位置
  • source

    • /root/source
    • runServer 服务器 jar包存放的根目录
  • logs

    • /root/logs
    • runServer 服务器 日志文件根目录
  • javaParameter

    • -Xmx512m -Xms256m -Duser.timezone=Asia/Shanghai
    • runServer 服务器 java 命令启动参数
  • arguments

    • runServer 服务器 -jar 启动的额外参数 比如 --spring.profiles.active=dev

部分截图:

Jenkins构建java01

二、在Jenkins项目中增加代码源

如果有多个项目组合编译,建议使用Jenkins触发构建的模式来按顺序编译其他依赖项目,不要直接在这里配置多个代码源(会增加编译脚本编写的复杂度,且定制程度太强,没有复用性了)

Jenkins构建java02

三、在Jenkins项目中配置构建相关设置

Jenkins构建java03

四、在Jenkins项目中配置编译工具

Jenkins构建java04

五、在Jenkins项目中配置shell脚本来完成主要功能

此过程分为3步:

  • 第一步
    • 更新远程运行服务的部署脚本
    • 检查远程服务器上必要的资源文件夹及文件情况,不符合要求就开始创建
      Jenkins构建java05

git-pull.sh 脚本:

#!/usr/bin/env bash
resource_dir=$1
# backup_dir检测
if  test -d ${resource_dir};then
     echo ${resource_dir}" 资源目录已存在"
     cd ${resource_dir}
     git pull
else
    cd "/root"
    git clone  git@code.aliyun.com:lc-private/shell-deployment.git
fi 

# 第一个参数是当前部署脚本存放的位置 

source-init.sh 脚本:

#!/usr/bin/env bash
root_source=$1
root_logs=$2
# /root/source检测
if  test -d ${root_source};then
     echo ${root_source}" 资源目录已存在"
else
   mkdir ${root_source}
fi
# /root/logs检测
if  test -d ${root_logs};then
     echo ${root_logs}" 日志目录已存在"
else
   mkdir ${root_logs}
fi
#要构建的项目名称
project_name=$3
# 运行环境的jar存放位置
source=${root_source}/${project_name}
if  test -d ${source};then
     echo ${source}" 运行目录已存在"
else
   mkdir ${source}
fi

# 第一个参数是当前运行环境的jar包存放根位置 /root/source
# 第二个参数是当前运行环境的日志存放位置 /root/logs
# 第三个参数是当前运行环境的jar包存放位置 test-config
# 这个脚本应该在当前运行环境上的服务器执行执行顺序为1
  • 第二步
    • Jenkins下寻找执行文件拷贝到远程运行服务器上

Jenkins构建java06

source-init.sh 脚本:

#!/usr/bin/env bash
# !/bin/sh
jenkins_home=${JENKINS_HOME}
# Jenkins的工作目录
jenkins_workspace=${jenkins_home}"/workspace"
#要构建的项目名称
project_name=$1
#Jenkins项目名称
jenkins_project_name=$2
#Jenkins编译项目相对路径
jenkins_project_target=${project_name}/"target"
if [[ "$project_name" = "$jenkins_project_name" ]];then
     echo "Jenkins忽略当前project_name属性寻址 :"${project_name}
else
    jenkins_project_target=${jenkins_project_name}/${jenkins_project_target}
fi
# Jenkins编译生成的jar包中间的相对路径  /root/data/jenkins_home/workspace/test-eureka/target/
jenkins_target=${jenkins_workspace}/${jenkins_project_target}
# jar全名,带后缀
jar_name=$3
# 运行服务器位置  root@172.16.10.211
server_domain=$4
# 运行环境的jar文件存放根目录
root_source=$5
# 运行环境的jar存放位置
source=${root_source}/${project_name}
scp -C -o StrictHostKeyChecking=no -r ${jenkins_target}/${jar_name} ${server_domain}:${source}

# 第一个参数为项目名称  account-server
# 第二个参数为Jenkins项目名称  production-account-server
# 第三个参数是jar包的名称带后缀  sn-eureka-0.0.1-SNAPSHOT.jar
# 第四个参数是当前运行环境的服务器位置 root@xxx.xxx.xxx.xxx
# 执行顺序为2 这个脚本需要配置第四个参数所对应的服务器ssh  pubkey  需要放到 jenkins  /var/jenkins_home
  • 第三步
    • 检查并启动服务,反馈过程及结果给Jenkins控制台

Jenkins构建java07

java.sh 脚本:

#!/usr/bin/env bash
JAVA_HOME=$1
JRE_HOME=${JAVA_HOME}/jre
JAVA_BIN=${JAVA_HOME}/bin
CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar:${JRE_HOME}/lib
PATH=$PATH:${JAVA_HOME}/bin:${JRE_HOME}/bin
export JAVA_HOME JRE_HOME PATH CLASSPATH
echo "path "${PATH}
echo "java_home "${JAVA_HOME}
echo "jre_home "${JRE_HOME}
echo "classpath "${CLASSPATH}
RUNNING_USER=${USER}
#要运行的项目名称
project_name=$2
# 运行环境的jar文件存放根目录
root_source=$3
# 运行环境的jar存放位置
source=${root_source}/${project_name}
# jar全名,带后缀
jar_name=$4
log_root=$5
shell_root=$6
# 参数有空格 需要用引号引起来 显示当做字符串传递
java_parameter=${7//","/" "}
arguments=${8//","/" "}

echo "参数=>>> start >>>>>>>>>>>>>>>>>>>>>"
echo "JAVA_HOME:"${JAVA_HOME}
echo "project_name:"${project_name}
echo "root_source:"${root_source}
echo "jar_name:"${jar_name}
echo "log_root:"${log_root}
echo "shell_root:"${shell_root}
echo "java_parameter:"${java_parameter}
echo "arguments:"${arguments}
echo "参数=>>> end >>>>>>>>>>>>>>>>>>>>>"

log_file=${log_root}"/"${project_name}".log"
psid=0
function initPsid(){
    javaps=`jps -l | grep "${project_name}/${jar_name}"`
    if [[ -n "$javaps" ]]; then
        psid=`echo ${javaps} | awk '{ print $1}'`
    else
        psid=0
    fi
}
function main(){
    initPsid
    if [[ ${psid} -ne 0 ]]; then
        kill -s 9 ${psid}
        echo "已杀死 "${psid}
    fi
    #有内核不兼容
#    JAVA_CMD="nohup java -Xmx1024m -Xms512m  -Duser.timezone=Asia/Shanghai -jar ${source}/${jar_name} &> /dev/null &"
#    su - ${RUNNING_USER} -c "${JAVA_CMD}"
    JAVA_CMD="java ${java_parameter} -jar ${source}/${jar_name} ${arguments}"
    echo "JAVA_CMD:"${JAVA_CMD}
    nohup ${JAVA_CMD} &> ${log_file} &
    initPsid
    if [[ ${psid} -ne 0 ]]; then
        ${shell_root}"/exec-java/java-log.sh" ${log_file}
        echo -e "\n===================== start [OK] pid=${psid} ====================="
        exit 0
    else
        echo -e "\n===================== start [FAILED], $? ====================="
    fi
}
main

# 第一个参数是java的环境变量  JAVA_HOME
# 第二个参数是当前运行环境的jar包存放位置 eureka
# 第三个参数是当前运行环境的jar包存放位置根目录 /root/source
# 第四个参数是jar包的名称带后缀  sn-eureka-0.0.1-SNAPSHOT.jar
# 第五个参数是日志根目录  /root/logs
# 第六个参数是脚本执行根目录  /root/shell-deployment
# 第七1个参数是 java 命令启动参数 比如 -Xmx1024m
# 第七2个参数是 java 命令启动参数 比如 -Xms512m
# 第七3个参数是 java 命令启动参数 比如 -Duser.timezone=Asia/Shanghai
# 第八个参数是 -jar 启动的额外参数 比如 --spring.profiles.active=dev
#/root/shell-deployment/exec-java/java-log.sh ${logRoot}/${projectName}.log
#nohup java -Xmx1024m -Xms512m  -Duser.timezone=Asia/Shanghai -jar /root/source/flow-dashboard-server/a-flow-dashboard-0.0.1-SNAPSHOT.jar | tee /root/logs/flow-dashboard-server.log
#java -Duser.timezone=Asia/Shanghai -jar a-crawler-w-0.0.1-SNAPSHOT.jar --spring.profiles.active=pod

java.sh 脚本中应用了一个 java-log.sh脚本,以下是 java-log.sh脚本内容:

#!/usr/bin/env bash
log_file=$1
echo ">>>>>>>>>>>>>>>>>>>> 启动日志输出 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ">>>>>>>>>>>>>>>>>>>> 预祝一切正常 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
/usr/bin/expect <<EOF
set timeout 120
spawn tail -f ${log_file}
expect "JVM running for"
exit
#wait
EOF

需要说明一下:
这个脚本使用了 expect来做交互式通知,需要在远程运行服务器上安装此组件,当然这个工作会在发布系统客户端初次启动的时候完成这个工作

到此,java项目的发布部署完成,还有一种将项目发布到没有公网ip的服务器的方案,限于篇幅,这里就不介绍了。

个人公众号

0

评论区