本文来自网易云社区linux
文/洪晓欢
git
自从使用了自动部署平台,环境部署变得简单不少,在尝到甜头的同时也有问题随之产生。开发修改了代码或修复了bug后告知QA须要部署环境,经常使用部署方式是:
选择环境-定义部署版本-一键部署-等待环境和实例部署完成。
因为项目较特殊,须要自定义一键部署会覆盖的config文件内容,所以适用于项目的部署方式:
选择环境-定义构建版本-构建版本-等待构建完成-部署实例-等待实例部署完成-到服务器上执行脚原本替换与环境相关的一些配置文件。
能够想象,一次两次的手工触发平台还能忍受,若是一天屡次或还须要切换部署分支又或者代码编译不经过,QA的效率会受到较大影响。
github
因而想到调用自动部署平台现有的API,但手工调用API后仍是须要人工干预:如校验是否构建和部署成功、须要更新token。因此进行了如下实践来完全解放人力进行真正的自动化部署。
web
几种利用自动部署平台进行部署的对比:
shell
自动部署平台使用方式 | 是否须要认为检查 | 能完美结合Jenkins |
---|---|---|
浏览器点击 | 是 | 不能 |
手工调用API | 是 | 不能 |
下文实践的方式 | 否 | 能 |
调用自动部署平台的API,须要知道如何在服务器内发送请求并获取到返回值,这样才能完成你预期的操做。比较通用的有两种方法: 1)经过编程语言实现 好比Java程序:各自有http请求的相关方法,编写完成后编译执行达到目的,这种方式虽然较为熟悉但过于重量级,执行一个源文件还须要引入依赖包等,最致命的是太笨拙,分支等参数写死在代码中,牵一发而动全身,即便变化的参数写在一个配置文件中,在须要修改如分支的值还要编辑文件,放弃之。 好比Python、Perl:对熟悉编程的人来讲Python、Perl这类标准的编程语言可能更快,但shell脚本的学习成本更低,代码也更简约。考虑到仅在linux里实现,遵循“KEEP IT SIMPLE,STUPID”的原则,未采用Python或Perl。 2)使用命令行工具 尝试了两种工具:curl和wget。curl基于libcurl库,这个库是一个稳定的跨平台的类库,任何人能够无偿使用其API进行开发,wget仅支持命令行方式运行,没有类库,不提供API,二者都支持http协议,都能抓取网页信息,具体的使用方法请--help。 curl命令调用接口:
编程
wget调用接口后的文件: json
前者直接返回结果:一个json object。后者会生成一个文件,文件内容为请求返回的结果。不选择wget的两个缘由:其一,太多的文件生成,每次执行wget就生成一个文件,假设一次完整部署须要调用N个接口,一天须要部署M次,当前文件夹下会产生N*M个文件,固然你能够每次调用前或后删除文件,这又多了一次操做;其二,须要读取文件内容,仅一个json对象不必花费如此大的精力。
api
不一样收发请求方式的对比:
数组
服务器收发请求方式 | 是否有依赖包 | 返回结果的解析成本 | 学习成本 | 传参是否灵活 |
---|---|---|---|---|
Java程序 | 是 | 低 | 较高 | 否 |
curl工具 | 否 | 低 | 低 | 是 |
wget工具 | 否 | 较高 | 低 | 是 |
既然已经获取到接口返回,下一步就是对返回值进行提取来做为具体操做的判断,使用Java的json包解析json是很是熟悉和简单的,但抛弃Java的状况会怎样,使用sed、awk解析和拼接?若是只是键和值的简单列表,又有较强的操纵能力,能够尝试,但从开放的API返回值来看,部分具备数组和复杂的对象,硬上的话花费的时间还不如选择编程语言了,json这类具备特定格式的文本不会被linux忽视,jq工具解决了解析的问题。
浏览器
jq是一个轻量级和灵活的命令行json处理器,由C语言编写而且运行时无依赖,适用于几乎全部平台,你能够把它想象成专门处理json数据的sed命令,用它来切割和筛选、映射和转换结构化数据。更多的jq介绍可访问官网:http://stedolan.github.io/jq/,不只提供了各类平台能直接运行的二进制文件:
还有完整的使用手册:
除了经常使用的文本输出格式化、json查询,更有运算、内置函数、条件比较、变量声明、自定义函数等高级功能。
json解析方式的对比:
服务器上解析json方式 | 学习成本 | 功能是否强大 | 复杂度 |
---|---|---|---|
awk、sed工具 | 高 | 是 | 较高 |
jq工具 | 低 | 是 | 低 |
注意:debian系统须要下载并安装deb文件,若是没有必定的权限是没法安装的,须要提交任务请SA安装。
发送请求和解析返回值的方式都已肯定,接下来就开始编写shell脚本。整个脚本的设计思路简单清晰:每发送一次请求后获取指定返回值,对比指望值来判断是否符合预期。项目中涉及到几个接口的调用和判断:
获取token—>判断返回码—>指定部署分支—>判断返回码—>构建版本—>判断构建状态—>部署实例—>判断实例状态。
其中构建版本和部署实例须要循环调用,循环体内判断构建和部署状态,一旦成功跳出循环,超过循环次数还未成功视为失败则退出程序。正常状况下构建和部署在必定时间内能成功,不须要循环等待和判断状态,但若是出现偶尔获取源码失败或部署平台自己偶发问题而引发的响应滞后,仍是容许多等待几回的。一开始在循环体内判断有异常跳出循环,几回执行后发现异常值没法穷举的,改为了判断成功状态。用户执行脚本需定义一个参数:分支名。
if [ $estatus = "build_succ" ];then DEPLOY_URL1=http://omad.hz.netease.com/api/cli/deploy?token= DEPLOY_URL2="&moduleId=真实ID&envId=真实ID&instanceId=真实ID" DEPLOY_URL="$DEPLOY_URL1$token$DEPLOY_URL2" DEPLOY_CMD=`curl $DEPLOY_URL` deploy_code=`echo $DEPLOY_CMD | jq .code` #判断接口返回值 if [ $deploy_code -eq 200 ]; then sleep 3 istatus_count=0 #循环并判断环境状态和实例状态 while [ $istatus_count -ne 10 ] do ISTATUS_URL1=http://omad.hz.netease.com/api/cli/istatus?token= ISTATUS_URL2="&envId=真实ID&instanceId=真实ID" ISTATUS_URL="$ISTATUS_URL1$token$ISTATUS_URL2" ISTATUS_CMD=`curl $ISTATUS_URL` istatus=`echo $ISTATUS_CMD | jq .status | sed 's/^"//g' | sed 's/\"//g'` ideployStatus=`echo $ISTATUS_CMD | jq .deployStatus | sed 's/^"//g' | sed 's/\"//g'` if [ $istatus != "running" -o $ideployStatus != "success" ]; then let istatus_count++ sleep 5 else break fi done else echo "deploy error:$deploy_code" exit 1 fi else echo "estatus error:$estatus" exit 1 fi
脚本调试中遇到的问题可能是语法和格式错误,好比使用变量时缺乏变量符、if判断的格式书写错误、拼接url出错等。
至此,符合现有环境的自动部署脚本完成,接下来就是利用Jenkins进行自动触发。推荐使用参数化构建过程来肯定分支名,在一个环境须要切换多个分支时比较灵活和下降输入错误:
构建后发现job构建成功,服务器上确实部署成功但没有应用进程启动,脚本单独在服务器上执行并无问题,询问了大牛和搜索一些资料后知道了还须要设置一个jenkins的环境变量,部署后重启的是后台进程,jenkins每次构建结束会默认kill这类进程。避免进程被杀掉的简单方法就是修改jenkins的环境变量BUILD_ID的值,从而让Jenkins认为此进程不是由Job的构建过程衍生的。官方说明:https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller。
符合项目的自动部署操做已集成在Jenkins中,若是能定义部署的触发条件就让“自动”变得更有意义,配置源码管理和构建触发器让Jenkins定时查询分支是否有更新,若是有更新就触发构建的shell进行环境部署:
一个job完成了根据定义的分支进行代码检测+触发自动部署+自定义脚本。
此次实践必定程度上提高了QA的工做效率,部署一次环境不再用在浏览器、服务器上花费至少3分钟的时间,也节省了开发和QA的沟通成本,开发不用通知QA代码是否更新,在项目频繁有代码提交的时候效果更为突出。
对于自动部署脚本自己还存在一些值得改进的地方,好比适用于多个应用、环境和实例构建部署的状况,这须要编写更复杂的脚本将三种值都做为参数传入。
自动部署只是项目持续集成中的一个环节,自动部署后须要根据不一样状况触发冒烟和回归测试,再进行静态代码检查及测试覆盖率统计,这些工做后续都须要完善。
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经做者洪晓欢受权发布。