使用shell脚本实现java灰度发布
脚本使用环境:
1、操作系统:centos 6.5 64位
2、代码使用gitlab进行管理
3、代码每次上线通过tag控制
4、前端使用haproxy实现负载均衡,使用haproxy socat实现RS的平滑上下线
5、WEB container使用tomcat实现
6、项目构建使用maven
使用脚本注意事项:
1、 发布机器需要能够解析web服务器主机名,并且配置ssh通信
2、 变量中的目录以及用户等信息需要自己创建,脚本没有做判断自己创建。我这里web服务器是使用ansible进行部署的,相关目录和用户都会自动创建。
3、代码的部署使用tag,但是代码的更新使用软连接来控制,回滚则切换到上一个软连接
4、由于java是编译型语言,我们使用maven来进行编译,所以需要安装maven环境。
5、关于环境配置文件:配置文件为自己手动维护,每次都是删除git仓库拉取下来的配置文件,把对应环境的代码文件复制进编译目录进行编译。
脚本代码大概的步骤如下:
#!/bin/bash # 设置时间变量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 项目名称,建议和gitlab仓库名称一致 project= # 本地代码目录(gitlab拉取代码后存放目录) CODE_DIR=/data/gitlab/"$project" # 临时代码目录,用来修改配置文件和编译打包代码 TMP_DIR=/data/tmp/"$project" # 用来存放war包 WAR_DIR=/data/war/"$project" # 对应环境配置文件 deploy_conf=/data/conf/pro/"$project"/* # 代码中的配置文件路径 local_conf=$TMP_DIR/src/main/resources/config # 远程主机名称 REMOTE_HOST="tomcat-01 tomcat-02" # 远程主机代码目录 REMOTE_CODE_DIR=/data/webapps/"$project" # 远程主机用户 REMOTE_USER=root # 远程主机war包存放目录 REMOTE_WAR_DIR=/data/war/ # 代码临时目录 CODE_TMP=/data/code_tmp/ # 上线日志 DEPKOY_LOG=/data/log/pro_log.log # 脚本使用帮助 usage(){ echo $"Usage: $0 [deploy tag | rollback_list | rollback_pro ver]" } # 拉取代码 git_pro(){ if [ $# -lt 1 ];then echo "请传入tag" exit 1 fi tag=$1 cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代码失败" exit 10 fi cd $CODE_DIR && git pull 2>/dev/null >/dev/null # 推送代码到临时目录 rsync -avz --delete $CODE_DIR/ $TMP_DIR/ 2>/dev/null >/dev/null } # 设置代码的配置文件 config_pro(){ echo "设置代码配置文件" rm -f $local_conf/config.properties ......... } # 打包代码 tar_pro(){ echo "本地打包代码" cd $TMP_DIR && /usr/local/maven/bin/mvn clean compile war:war && cp target/"$project".war "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war } # 推送war包到远端服务器 rsync_pro(){ echo "推送war包到远端服务器" for host in $REMOTE_HOST;do scp "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war [email protected]$host:$REMOTE_WAR_DIR done } # 解压代码包 solution_pro(){ echo "解压代码包" for host in $REMOTE_HOST;do ssh [email protected]$host "unzip "$REMOTE_WAR_DIR""$project"_"$tag"_"$CTIME".war -d "$CODE_TMP""$project"_"$tag"_"$CTIME"" 2>/dev/null >/dev/null done } # api测试 test_pro(){ # 运行api测试脚本,如果api测试有问题,则退出部署 if [ $? != 0 ];then echo "API测试存在问题,退出部署" exit 10 fi } # 部署代码 deploy_pro(){ echo "部署代码" ................... sleep 3 # 执行api测试 test_pro ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 列出可以回滚的版本 rollback_list(){ echo "------------可回滚版本-------------" ssh [email protected]$REMOTE_HOST "ls -r "$CODE_TMP" | grep -o $project.*" } # 回滚代码 rollback_pro(){ echo "回滚中" for host in $REMOTE_HOST;do ............................. sleep 3 ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 记录日志 record_log(){ echo "$CTIME 主机:$REMOTE_HOST 项目:$project tag:$1" >> $DEPKOY_LOG } # 代码执行选项设置 main(){ case $1 in deploy) git_pro $2; config_pro; tar_pro; rsync_pro; solution_pro; deploy_pro; record_log $2; ;; rollback_list) rollback_list; ;; rollback_pro) rollback_pro $2; record_log; ;; *) usage; esac } main $1 $2
使用shell实现php代码自动发布
脚本适应环境:
1、操作系统:centos 6.5 64位
2、代码使用gitlab进行管理
3、代码每次上线和回滚通过tag控制
补充:如果需要在你的企业使用我的这种部署方式,还需要有相应环境规范以及git分支管理规范。
使用脚本注意事项:
1、 发布机器需要能够解析web服务器主机名,并且配置ssh通信
2、 变量中的目录以及用户等信息需要自己创建,脚本没有做判断自己创建。我这里web服务器是使用ansible进行部署的,相关目录和用户都会自动创建。
3、代码的部署使用tag,回滚原则为回滚到上个tag版本,所以部署脚本本身没有备份代码。
4、如果需要过滤一些临时目录或者日志目录,可以在rsync推送代码的时候使用–exclude选项进行过滤,示例脚本中过滤了.git目录和config.php文件是不会部署的。
#!/bin/bash # 设置时间相关变量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 项目名称,建议和gitlab仓库名称一致 project=test # 本地代码目录(gitlab拉取代码后存放目录) CODE_DIR=/data/gitlab/pro/$project/ # 远程主机 REMOTE_HOST="LNMP-01.fblinux.com LNMP-02.fblinux.com" # 远程主机代码目录 REMOTE_DIR=/data/www/fblinux/ # 远程主机用户 REMOTE_USER=root # 远程主机代码执行用户 CODE_USER=php # 上线日志 DEPKOY_LOG=/data/log/pro_log.log #脚本使用帮助 usage(){ echo $"Usage: $0 [deploy tag]" } #拉取代码 git_pro(){ if [ $# -lt 1 ];then echo "请传入tag" exit 1 fi echo "拉取代码" cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代码失败" exit 10 fi cd $CODE_DIR && git pull } #推送代码服务器 rsync_pro(){ for host in $REMOTE_HOST;do echo "推送代码到服务器$host" rsync -rPv -P --delete --exclude="config.php" --exclude=".git" $CODE_DIR -e 'ssh -p 22' [email protected]$host:$REMOTE_DIR if [ $? != 0 ];then echo "推送代码失败" exit 10 fi echo "代码授权" ssh [email protected]$host "chown -R $CODE_USER $REMOTE_DIR" if [ $? != 0 ];then echo "代码授权失败" exit 10 fi done } #记录日志 record_log(){ echo "$CTIME 主机:$REMOTE_HOST 项目:$project tag:$1" >> $DEPKOY_LOG } main(){ case $1 in deploy) git_pro $2; rsync_pro; record_log $2; ;; *) usage; esac } main $1 $2