作为一名java开发,目前基本都是windows上开发应用,linux上部署发布应用。
关于发布,一般都是本地手动打包,使用ftp工具上传linux服务器,然后使用命令行启动应用。对于频繁发布的情况,手动发布会浪费大量时间,而且手动打包针对不同环境(dev,sit,uat,pro)容易造成配置文件搞错导致发布出问题,其中带来的负面影响可能更大。而且针对大型的分布式系统,此问题尤为突出,每日新提交的代码本就可能导致系统异常,再因为发布问题,则版本的质量和稳定性都将难以控制。
持续集成就可以解决上述描述的问题,自动构建发布,并且可以定时构建,节省手动发布时间成本及避免人工打包出错,同时及时发现系统开发集成过程中产生的问题。
Jenkins是个开源免费的持续集成工具,有很多插件支持扩展,功能强大。前段时间项目的测试环境jenkins服务器被回收,项目发布又回到了手动发布的原始时代,习惯了点一下发布,猛地还有点不习惯。于是乎了解下jenkins的安装和使用,现整理如下。
Jenkins安装
jenkins官网上支持多种安装方式,选择一个熟悉的方式-war包安装。
在线文档:https://www.jenkins.io/zh/doc/book/installing/
机器上需要先安装配置jdk
jdk安装配置
jdk需要先安装配置,否则无法启动jenkins…
解压后配置环境变量,编辑/etc/profile
- vim /etc/profile
- shift+G(移动到文件末尾)
- 加入配置信息
export JAVA_HOME=/usr/local/software/java/jdk1.8.0_191
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
- 刷新环境变量 source /etc/profile
下载并安装jenkins
1.下载jenkins.war:wget http://mirror.serverion.com/jenkins/war-stable/2.222.3/jenkins.war
2.启动:nohup java -jar jenkins.war & 启动完成后 后台会打印一段用户首次登陆的信息:
3.登陆 输入上述打印的密码,然后开始进行插件安装,有两个选项,推荐安装和自定义。首次使用我选择了推荐安装,后面需要什么插件再自行安装。
Jenkins配置及插件安装
安装完成后,还需要配置并安装一些插件,才可以进行Java maven应用的构建
前置条件:本机先安装并配置jdk,maven,git(svn)。
也可以使用jenkins的自动安装。
插件安装
Jenkins -> 系统管理 -> 插件管理 -> 可选插件 搜索响应插件安装,安装完成需要重启,可勾选自动重启
Maven Integration plugin:支持创建maven项目
publish-over-ssh:用于ssh传输,远程发布需要
Role-based Authorization Strategy:权限配置
Locale plugin
Localization Support Plugin
Localization: Chinese (Simplified):以上三个用于汉化
maven安装
同jdk安装,解压后配置环境变量
配置信息
export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.3
export PATH=$MAVEN_HOME/bin:$PATH
git安装
1.下载git https://github.com/git/git/releases 下载 改后缀为 .tar.gz 并解压,进入解压目录
2.先安装依赖yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker
3.如果已安装git 先卸载 yum remove git
4.编译git源码 make prefix=/usr/local/git all
5.安装git make prefix=/usr/local/git install
6.配置环境变量 vim /etc/profile , 底部加入然后重新加载source /etc/profile
PATH=$PATH:/usr/local/git/bin
export PATH
7.检查 git --version
jenkins配置jdk,maven,git
Jenkins -> 系统管理 -> 全局工具配置
jenkins配置远程服务器
Jenkins -> 系统管理 -> 系统配置 -> Publish over SSH
配置远程服务器指的是需要发布应用的目标服务器,本机构建完应用生成jar包后jenkins会根据配置拷贝jar包到远程服务器指定目录
点击新增输入服务器信息,输入完毕后点击高级,输入密码保存即可
Jenkins创建任务
创建任务
1.创建maven项目
2.源码管理 选择Git 输入仓库URL 选择/配置用户名密码 ,指定分支
3.Build中输入构建选项 如 “clean package -Dmaven.test.skip=true”
4.Post Steps(后置步骤) 中 选择 “send files or execute commands over SSH”
选择远程服务器并配置
Source files:**/*.jar
Remove prefix: target
Remote directory:/home
Exec comman:
cd /home
source /etc/profile
/bin/sh run.sh xxx.jar
说明及注意事项:
1.若构建的任务依赖其他任务,选择前置构建步骤并输入所依赖任务,选择锁定
2.第4步为指定构建的jar包并指定远端目录(远端目录即可以在此配置也可以在远程服务器处配置,最终会合并处一个远程目录地址),Exec comman为最终需要执行的shell脚本,jar包复制到远端后,需要启动,可以在此处直接输入启动命令,也可以使用预先保存的脚本启动,执行前source /etc/profile确保java等命令可以执行。
3.-pl xxx -am clean package 可以构建关联的依赖应用
启动脚本
run.sh
#!/bin/sh
###
# linux自启动jar包脚本
# 支持start|restart|stop|status|null,默认restart
# start进程不存在才会启动
# restart进程不存在直接启动,存在先kill再启动
# stop进程存在才杀死
# status进程是否存在
# 为空则执行restart
###
jarname=$1;
pid='';
function findPid() {
pid=`ps -ef|grep $jarname | grep -v grep| grep -v /bin/sh|awk '{print $2}'`;
}
function start() {
if [ ! -n "$pid" ]; then
run;
else
echo "$jarname already started"
fi
}
function restart() {
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
run;
else
echo "$jarname already started, kill pid is $pid"
kill -9 $pid
findPid;
if [ ! -n "$pid" ]; then
run;
else
echo "$jarname pid can not killed, start failed"
fi
fi
}
function run() {
echo "$jarname is start..."
nohup java -Xms128m -Xmx512m -jar $jarname >$jarname.log 2>&1 &
sleep 1
findPid;
echo "$jarname start finish, pid is $pid"
}
function status(){
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
else
echo "$jarname already started, pid is $pid"
fi
}
function stop() {
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
else
echo "$jarname already started, kill pid is $pid"
kill -9 $pid
findPid;
if [ ! -n "$pid" ]; then
echo "$jarname killed success."
else
echo "$jarname killed failed."
fi
fi
}
findPid;
if [ ! -n "$jarname" ]; then
echo "jar package name must be specified";
else
case $2 in
start)
start
;;
stop)
stop
;;
status)
status
;;
*)
echo "support:start|restart|stop|status|null, default is restart"
restart
;;
esac
fi;
exit 0
启动脚本增强版,带备份
run.sh
#!/bin/sh
###
# linux自启动jar包脚本
# 支持start|restart|stop|status|null,默认restart
# start进程不存在才会启动
# restart进程不存在直接启动,存在先kill再启动
# stop进程存在才杀死
# status进程是否存在
# 为空则执行restart
###
jarname=$1;
pid='';
function backFile() {
backfilename=${jarname%%.jar*}_$(date "+%Y%m%d%H%M%S").jar;
echo "开始备份";
cp $jarname ./backFiles/${backfilename};
echo "备份完成:`pwd`/backFiles/${backfilename}";
}
function isSuccess() {
sleep 8;
findPid;
if [ ! -n "$pid" ]; then
echo "$jarname start failed"
else
echo "$jarname start success"
fi
}
function findPid() {
pid=`ps -ef|grep $jarname | grep -v grep| grep -v /bin/sh|awk '{print $2}'`;
}
function start() {
if [ ! -n "$pid" ]; then
run;
else
echo "$jarname already started"
fi
}
function restart() {
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
run;
else
echo "$jarname already started, kill pid is $pid"
kill -9 $pid
findPid;
if [ ! -n "$pid" ]; then
run;
else
echo "$jarname pid can not killed, start failed"
fi
fi
}
function run() {
backFile;
echo "$jarname is start..."
nohup java -Xms2048m -Xmx2048m -jar $jarname >/dev/null 2>&1 &
sleep 1
findPid;
echo "$jarname start finish, pid is $pid"
isSuccess;
}
function status(){
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
else
echo "$jarname already started, pid is $pid"
fi
}
function stop() {
if [ ! -n "$pid" ]; then
echo "$jarname pid is not exist"
else
echo "$jarname already started, kill pid is $pid"
kill -9 $pid
findPid;
if [ ! -n "$pid" ]; then
echo "$jarname killed success."
else
echo "$jarname killed failed."
fi
fi
}
findPid;
if [ ! -n "$jarname" ]; then
echo "jar package name must be specified";
else
case $2 in
start)
start
;;
stop)
stop
;;
status)
status
;;
*)
echo "support:start|restart|stop|status|null, default is restart"
restart
;;
esac
fi;
exit 0