Maven+Git+Shell持续集成教程
http://blog.csdn.net/xlgen157387/article/details/50353317
更改启动端口
java -jar jenkins.war --httpPort=7000
Maven+Git+Shell+Tomcat+Java Application方式配置所需插件
Git Plugin 用于配置项目的"源码管理"一项
Maven Integration plugin 用于创建maven 部署项目
配置JDK:
从位置: Global Tool Configuration->JDK配置,取消自动安装JDK的选项
jdk 配置.png配置MAVEN:
从位置: Global Tool Configuration->MAVEN配置,取消自动安装MAVEN的选项
maven 配置.png构件错误:mvn: not found
在构建步骤添加了一个Execute shell: mvn clean install -Pdev
在构建时提示下面错误
/tmp/jenkins5303088740826333885.sh: 2: /tmp/jenkins5303088740826333885.sh: mvn: not found
Build step 'Execute shell' marked build as failure
Finished: FAILURE
已经尝试过ssh登录服务器,检查过maven变量没有问题,但还提示这个错误
解决方法:
使用maven构件项目来构件
Maven构件项目增加Post-Steps
用于maven构件成功后执行的脚本
Post Steps.png
完整示例:
export BUILD_ID=build_release
build_path=${WORKSPACE}/buildAll/release
rsync -uvr "${build_path}/providerXXX/." "jufuns@192.168.1.100:/opt/providerXXX"
echo "provider synchronize success"
curl 'https://oapi.dingtalk.com/robot/send?access_token=6af3157c0ac425e744b2f7252883b2693f362463283bd1c437a7179c170d759e' \
-H 'Content-Type: application/json' \
-d '
{"msgtype": "text",
"text": {
"content": "### 开发环境更新完毕 ###"
},
"at":{
"atMobiles": ["158000111222"],
"isAtAll": false
}
}'
startup_all.sh 脚本主要用于重启服务,重启tomcat:
#! /bin/sh
start(){
echo "run all-provider..."
cd /opt/providers/all-provider/
nohup java -jar all-provider-1.5.0-dev.jar &
echo "run all-provider done"
echo "run event-listener..."
cd /opt/providers/event-listener/
nohup java -jar event-listener-1.5.0-dev.jar &
echo "run event-listener done"
echo "run tomcat..."
sh /opt/tomcat-8080/bin/startup.sh
echo "run tomcat done"
}
stop(){
echo "try to stop"
echo "kill tomcat"
ps -ef|grep tomcat|awk '{print $2}'|xargs kill
echo "kill all providers"
ps -ef|grep xxxx-provider|awk '{print $2}'|xargs kill
echo "stop done"
}
restart(){
echo "restart..."
stop;
echo "sleep 5 seconds to wait all service stop by soft"
sleep 5
start;
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage {start|stop|restart}"
sac
执行构件操作,发现启动脚本也echo 了一些东西出来,但ps -ef一下却没发现进程启动了,在网上找了一下资料,说是要有一个BUILD_ID的环境变量,所以在POST BUILD的Execute shell那里加上一句:
export BUILD_ID=XXXX
sh /opt/startup_all.sh restart
在重启后加入钉钉机器人通知功能:
1.在钉钉群里添加自定义机器人,复制机器人api URL
2.在重启脚本执行完后,通过curl 调用api
curl 'https://oapi.dingtalk.com/robot/send?access_token=6af3157c0ac425e744b2f7252883b2693f362463283bd1c437a7179c170d759e' \
-H 'Content-Type: application/json' \
-d '
{"msgtype": "text",
"text": {
"content": "### 开发环境更新完毕 ###"
},
"at":{
"atMobiles": ["158000111222"],
"isAtAll": false
}
}'
定时执行 - Poll SCM
Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作。如下图配置:
/5 * * * (每5分钟检查一次源码变化)
Build periodically:周期进行项目构建(它不关心源码是否发生变化),如下图配置:
H 2 * * * (每天2:00 必须build一次源码)
在 Schedule 中填写 0 * * * *。
<pre>
第一个参数代表的是分钟 minute,取值 0~59;
第二个参数代表的是小时 hour,取值 0~23;
第三个参数代表的是天 day,取值 1~31;
第四个参数代表的是月 month,取值 1~12;
最后一个参数代表的是星期 week,取值 0~7,0 和 7 都是表示星期天。
</pre>
所以 0 * * * * 表示的就是每个小时的第 0 分钟执行构建。
线上服务器处理篇
如果单纯用jenkins编译生成文件后,然后通过scp,或者ftp 等方式上传文件,
那每次都会上传很多文件,如果文件比较多,则影响服务器更新效率。
解决方法:
使用svn,来传输,因为svn 有识别有什么文件已修改,所以这种方式可以只上传发生变化的文件,而不用全部上传。
步骤:
1.在线上服务器搭建svn服务,并将发布的文件目录添加到svn
2.在jenkins 部署的服务器将线上服务器 发布文件的svn 目录 checkout下来
3.增加Jenkins Post-Step shell 脚本将maven生成的文件拷贝到svn目录。
4.通过svn add 命令和svn commit命令将新改动的文件提交svn
这里需要注意的是,maven生成的文件里包含很多多余文件,这需要手动切换到svn目录,并将这些多余文件忽略掉,这样不至于执行svn add . 的时候会吧文件都纳入svn中。
5.通过ssh命令发送一条重启服务的命令,例如:
ssh xxx@xxx.xx.xx.xx /opt/startup.sh
命令在文章最后参考
在使用这个方式来重启之前,需要先准备好ssh 自动认证 的条件。
(可以查看我另外一篇文章做参考: http://www.jianshu.com/p/be12171a3b14 )
当然,线上服务器应该人工来干预,例如数据库表的更新,程序的配置等,为了确保更新没有问题,所以一般来说,第5点只是一个可选的操作(能自动把更新的文件传到服务器上已经很不错了)
线上环境更新脚本示例:
#! /bin/sh
start(){
echo "run all-provider..."
cd /opt/jufuns/providers/all-provider/
nohup java -jar all-provider-1.5.0-release.jar &
echo "run all-provider done"
echo "run event-listener..."
#cd /opt/jufuns/providers/event-listener/
#nohup java -jar listener-1.5.0-release.jar &
echo "run event-listener done"
echo "run system-task..."
cd /opt/jufuns/providers/system-task/
##nohup java -jar systemtask-1.5.0-release.jar &
echo "run event-listener done"
echo "run tomcat..."
cd /opt/jufuns/tomcat-8090/bin
sh ./startup.sh
echo "run tomcat done"
}
stop(){
echo "try to stop"
echo "kill tomcat"
ps -ef|grep tomcat-8090|awk '{print $2}'|xargs kill -9
echo "kill all providers"
ps -ef|grep -e .*release|awk '{print $2}'|xargs kill
echo "stop done"
}
restart(){
echo "restart..."
stop;
echo "sleep 10 seconds to wait all service stop by soft"
sleep 10
start;
}
#check if need update files
if [ "$2" = "-update" ] ; then
echo "update all files..."
cd /opt/jufuns/providers
# 这里要使用 --force 参数强制更新,避免遇到错误终止更新
svn up . --force
fi
case "$1" in
start)
start
ps -ef|grep cn
ps -ef|grep tomcat-8090
;;
stop)
stop
ps -ef|grep cn
ps -ef|grep tomcat-8090
;;
restart)
restart
ps -ef|grep cn
ps -ef|grep tomcat-8090
;;
*)
echo "Usage {start|stop|restart} [-update]"
esac
开发环境更新脚本示例:
从build目录复制文件到指定位置脚本 copy_from_build.sh
! /bin/sh
if [ -z $1 ] ; then
echo "Provider-Directory-Name is requried!"
echo "Usage: {Provider-Directory-Name} {Target-Provider-Name}"
exit 0
fi
#if [ -z $2 ] ; then
# echo "Target-Provider--Name is requried!"
# echo "Usage: {Provider-Directory-Name} {Target-Provider-Name}"
# exit 0
#fi
BUILD_ROOT=/home/vital/.jenkins/workspace/MeiHaoHui-Dev/buildAll/dev/$1
TARGET_ROOT=/opt/providers/$2
if [ ! -d $TARGET_ROOT ]; then
mkdir -p $TARGET_ROOT
fi
echo "ready to update from path ${BUILD_ROOT} to path ${TARGET_ROOT}...";
jar_file=`find $BUILD_ROOT -maxdepth 1 -iname "*.jar"`
if [ "$3" = "-tomcat" ]; then
echo "Using tomcat copying mode"
echo "execute shell: rm ${TARGET_ROOT}/WEB-INF"
rm -rf ${TARGET_ROOT}/WEB-INF
echo "rm done!"
echo "execute shell: /bin/cp -rf ${BUILD_ROOT} ${TARGET_ROOT}"
/bin/cp -rf "${BUILD_ROOT}/." "${TARGET_ROOT}"
echo "cp done!"
else
echo /bin/cp -rf "${jar_file}" "${TARGET_ROOT}/"
/bin/cp -rf "${jar_file}" "${TARGET_ROOT}/"
echo /bin/cp -rf "${BUILD_ROOT}/lib" "${TARGET_ROOT}/"
/bin/cp -rf "${BUILD_ROOT}/lib" "${TARGET_ROOT}/"
fi
echo "done"
startup_all.sh脚本(包含了copy_from_build.sh 的调用)
#! /bin/sh
start(){
echo "run all-provider..."
cd /opt/providers/all-provider/
find . -iname "*.jar" -maxdepth 1 -exec nohup java -jar {} \; &
echo "run all-provider done"
echo "run event-listener..."
cd /opt/providers/event-listener/
find . -iname "*.jar" -maxdepth 1 -exec nohup java -jar {} \; &
echo "run event-listener done"
echo "run system-task..."
cd /opt/providers/system-task/
find . -iname "*.jar" -maxdepth 1 -exec nohup java -jar {} \; &
echo "run system-task done"
echo "run tomcat..."
cd /opt/tomcat-8080/bin
sh startup.sh
echo "run tomcat done"
}
stop(){
echo "try to stop"
echo "kill tomcat"
ps -ef|grep tomcat-8080|awk '{print $2}'|xargs kill -9
echo "kill all providers"
ps -ef|grep -e cn-jufuns-residences.*dev|awk '{print $2}'|xargs kill
echo "stop done"
}
restart(){
echo "restart..."
stop;
echo "sleep 10 seconds to wait all service stop by soft"
sleep 10;
start;
}
#check if need update files
if [ "$2" = "-update" ] ; then
echo "update all files..."
update=/opt/copy_from_build.sh
$update "cn-jufuns-residences-all-provider" "all-provider"
$update "cn-jufuns-residences-event-listener" "event-listener"
$update "cn-jufuns-residences-search-provider" "search-provider"
$update "cn-jufuns-residences-systemtask" "system-task"
$update "cn-jufuns-residences-origin-web/web" "web" -tomcat
$update "cn-jufuns-residences-origin-admin/admin" "admin" -tomcat
fi
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage {start|stop|restart} [-update]"
esac
网友评论