以前的文章说过 由 PHP 转到 Java 以后,很是不适应的一点就是代码部署过程耗时长,调试不便,虽然可使用 debug,但有时候仍是须要修改代码,从新部署测试机系统,整个流程须要:css
再加上须要两台机器切换操做,步骤之间不连贯,须要在边上看着进度,以及时操做下一步。能够说,等到想要的代码上传到测试机运行,花儿都谢了。html
做为一个懒人,迫切地须要简化一下流程,虽然可能达不到像 PHP 同样秒传文件当即生效,也要尽可能快且方便地部署测试包,别操这么多心。本文就介绍我是怎么一步步优化测试部署流程的。git
文章欢迎转载,请尊重做者劳动成果,带上原文连接:http://www.cnblogs.com/zhenbianshu/p/8733103.htmlgithub
刚入职时,对 Java 的部署相关一脸懵逼,有同事给了一个脚本和两条命令,是为最原始的“自动部署系统”:web
nc -4l xxPort > ROOT.war
;mvn clean package project
;nc testIp xxPort < test-1.0.0.war
;nc 是 NetCat 的简称,这个小工具用于同步两台服务器间的文件,使用时,先在接收端监听一个端口并指定输出文件,再在发送端链接 IP 和端口,并指定输入流, nc 命令很简单,网络上资料也不少,这里再也不多提了。算法
这个脚本虽然比所有手动好了一些,能帮我少输两个命令(nc 服务端、重启命令),但是时间上并无缩短,但是乌龟似的上传速度真的不能忍,这时我开始想着怎么加速上传。docker
其实一开始我是想从硬件方面解决这个问题的,即便用网线。为此,买了一个网线转接头和一段网线,但是经过同事的设备测试发现转接头和网线都没问题,但是接到一块就不匹配(围笑)。shell
穷则思变,接着我考虑从软件方面解决这个问题。问了几个同过后,发现有的同事在用 rsync 同步文件,但是 rsync 同步文件的单位不是文件
吗?看了同事演示的上传后,感受心态崩塌,很差好读文档的后果啊,走了好多弯路。apache
这里简要介绍一下 rsync 的使用:json
服务端须要启动一个 rsync daemom 进程监听某一端口,默认配置文件在 /etc/rsyncd.conf
,以 module
为单位进行用户认证、权限校验、目标文件夹等配置,一个常见的 rsyncd 配置以下:
# general conf port=873 # 监听端口 max connections=500 log file=/var/log/rsyncd.log pid file=/var/run/rsyncd.pid # pid 文件 # module 可多个 [zbs] path = /data1/zbs # zbs模块的根目录 read only=no use chroot=no uid=root gid=root auth users=zbs // 要进行用户认证的用户名 secrets file=/etc/rsyncd.scrt # 用户名对应的密码存放文件,每行一个,都是以 "zbs:password" 的形式 ignore errors exclude = .git/ # 排除掉 .git 文件夹
而在客户端,咱们只须要使用 rsync [-option] fileOrDir rsync://{user}@{host}:{port}/{moduleName}/dir
就能够将本地文件同步到服务端了。
至于密码,可使用 --password-file=/path/to/pwdFile
的形式,也能够在调用 rsync 命令以前设置环境变量:export RSYNC_PASSWORD=XXXX
;
至于 rsync 的同步算法, 推荐陈皓大神的文章:RSYNC 的核心算法
rsync 解决了上传速度的问题,可是又引入了新的问题:我必须等着上传结束,而且上传结束后还要登录测试机手动重启 docker 服务,挺不方便的。
这时我开始打 rsync 源码的主意了,rsync 是一个开源软件,我考虑帮它加一个参数,让它帮我在文件上传结束后自动执行一些命令。
说作就作,从 rsync官网 下载到 rsync 的源码开始查看并动手修改。rsync 的源码代码量仍是挺大的,不过修改它咱们不须要通读,只修改读取参数并使用就好了。我将这个问题分为两个步骤:
首先在 proto.h
文件里添加函数声明: char *lp_callback(int module_id);
读取参数的相关代码在 load_param.c
文件内,首先添加变量声明、设置默认值,最后添加参数调用函数。
服务端文件同步的代码在 clientserver.c
文件内,主体是 rsync_module
函数,前面的一系列操做如用户认证、权限校验等咱们能够没必要管,找到最后一步,在其调用下一次同步函数前 添加以下代码(解释在注释中):
char * callback = lp_callback(i); // 读取 callback 参数 if (callback != NULL && strlen(callback) != 0) { char cmd[strlen(callback) + 2]; strcpy(cmd, callback); strcat(cmd, " &"); // system 命令会阻塞,须要在命令上添加 & 让它后台执行 system(cmd); // 使用 stdlib 的 system 执行 callback 命令 }
修改后的源码见:Github-zhenbianshu-rsyncCallback
这样,我给本身上传用的 module 添加一个脚本做为 callback,在每次上传完后,都会执行这个 callback 脚本,脚本里我能够配置上服务的重启,自动部署就实现了。
其实 tomcat 是能够自动部署的,须要配置 server.xml
的 Host 元素,将 autoDeploy 属性置为 true,文档:Tomcat Web Application Deployment。
但是咱们的服务是基于 docker-compose 进行部署的,若是修改 server.xml 还须要将文件映射到 docker image 里。
其中 docker 能够这么配置:
FROM tomcat:7-jre8 COPY server.xml /usr/local/tomcat/conf/
docker-compose 能够在 yml 配置文件里添加以下配置:
image: tomcat-base volumes: - ./path/server.xml:/usr/local/tomcat/conf/server.xml - ./path/webapps:/data1/project/webapps
这样,每当上传了新的 war 包,tomcat 就会自动监测到并从新部署服务;
此时,还有一个需求, war 包同步完成,重启完成后我不知道,得随时关注 tomcat 的服务日志,以尽快得知重启结果,及时测试,若是服务重启完就当即告诉我就最好了。
此时,我修改的 rsync 就有了做用了,使用 callback 参数在测试机启动一个脚本以监测 tomcat 的服务日志,服务重启完成后会输出 Server startup in xxx ms
,若是监测到有新的 log 输出,则发送一个通知告诉我。
callback 参数配置的脚本相似于:
#!/bin/bash docker-compose stop -t 0 `rm /data1/project/webapps/ROOT -rf` sleep 1 docker-compose start sleep 5 # 这里等待一会,使大量 tomcat 日志覆盖掉上一次重启的结果日志 date=`date "+%Y-%m-%d"` catalina_log="/data1/project/logs/catalina.$date.log" while : # 重复检测日志最后一行,直到输出了重启成功的标识 do finish=`tail -n 1 $catalina_log | grep 'Server startup'` if [ -n "$finish" ] then break fi sleep 0.1 done `curl -u "user:password" -d "uid=5715965217&text=succ" "messages/new.json"` # 调用接口发送通知
其实在测试机启动一个守护进程用来实时监测日志也是能够的,可是须要处理日志的新旧逻辑。
至于通知,有不少工具可使用,微博、QQ、微信、短信等通信工具都提供有对外的 http 接口,这个能够依各人喜爱选择使用。
最后把开发机上的 mvn 打包命令和 rsync 同步命令也包装成脚本,以下所示:
#!/bin/bash mvn clean -DskipTests=true package -Pwar -am -pl project file=`find /path/to/project/target -name "*.war"` export RSYNC_PASSWORD=123456 rsync -avz $file rsync://zbs@IP:PORT/zbs/ROOT.war
再给脚本添加一个 alias 别名 alias test="myshell.sh"
,真正的一键部署就完成了,在部署测试环境时,只须要在项目目录下输入一条命令 test
就开始自动部署了,这时候能够放手去喝杯水或作些其余事,等收到消息通知后,回来继续测试便可。
部门正在搭配 git 系统作自动部署测试系统,很是期待 push 过代码后就能够迅速测试的场景。果真,懒才是第一辈子产力啊~
关于本文有什么问题能够在下面留言交流,若是您以为本文对您有帮助,能够点击下面的 推荐
支持一下我,博客一直在更新,欢迎 关注
。