摘要:小公司嘛,人少事情多,IT部门更是,一个人顶好几个人用,部署更新上线,全靠手动,本地打包,哎呦,200多M,传到服务器慢慢等吧,用FTP,那速度,真让人着急,然后呢,JPS找到进程ID,KILL掉,再启动服务,一套流程下来,半条命没了,所有人都觉得这种日子没尽
小型公司告别手动部署的自救之路
小公司嘛,人少事情多,IT部门更是,一个人顶好几个人用,部署更新上线,全靠手动,本地打包,哎呦,200多M,传到服务器慢慢等吧,用FTP,那速度,真让人着急,然后呢,JPS找到进程ID,KILL掉,再启动服务,一套流程下来,半条命没了,所有人都觉得这种日子没尽头。
一天下来干不了别的,全是重复劳动,谁能受得了,所以啊,就想着能不能“偷懒”一下,提高点效率,起码能有点时间喝口水,要是能一键部署,那简直是天堂了,要是有全套CI/CD,那得花多少钱,想想就头疼,还是在现有的Jenkins上想想办法吧,写写脚本,看看能不能搞定。
核心就是那几个Shell脚本,停服务,启动服务,还有部署脚本,停服务脚本,参考了陈皮大哥的,改了改,加了个sleep 5,让它停的更彻底,主要就是用JPS找到包含JAR文件名的进程ID,然后KILL掉,那个APP_MAINCLASS,得替换成你项目JAR的名字啊,别忘了,这里面有个getpid函数,用`jps -l | grep $APP_MAINCLASS`来获取进程ID,简单粗暴,然后是stop函数,循环尝试KILL进程,最多三次,三次不行就来狠的,`kill -9`,强制KILL,之后还要再检查一下,进程是不是真死了,没死就继续尝试,哎,真是不让人省心。
启动脚本呢,就是把自己之前用的改了改,核心功能就是启动JAR文件,basepath,通过`${0}`得到脚本所在的目录,JVM参数,根据需求自己设置,内存大小,垃圾回收策略什么的,别忘了后台运行,用`nohup ... &>nohup.log &`,这样服务就能在后台跑,还能把日志输出到`nohup.log`,方便查看,省得自己盯着屏幕。
自动部署脚本,放在jenkins的Post Steps里,挺方便的,主要功能就是备份正在运行的JAR包,以时间戳命名,防止出问题还能回滚,然后从jenkins服务器复制最新的JAR包到目标服务器,再执行停服脚本,最后执行启动脚本,顺序别搞错了,备份很重要啊,不能上线出了问题,想恢复都没得恢复,大家都在想,这到底是怎么一回事。
这里面有些关键点,用`ssh -Tq`命令在远程服务器上执行命令,记得`source /etc/profile`加载环境变量,不然有些命令找不到,`rm -rf /data/app/test/xxx-1.0.0.jar.bak*`,删除旧的备份jar包;`mv /data/app/test/xxx-1.0.0.jar /data/app/test/xxx-1.0.0.jar.bak$DATE`,备份jar包,`scp`命令用于从jenkins服务器复制JAR包, `$IP`是部署服务器IP,`$jenkisIP`是jenkins服务器IP,记得提前配置jenkins服务器与部署服务器之间的SSH免密登录,不然每次都要输密码,也挺麻烦的。
这样下来,自动化部署基本就搞定了,手动部署的时间和精力能省不少,适合小公司,投入小,见效快,很多人看完这个故事,都会去想,这玩意靠谱吗,核心就是编写和优化停服、启动以及部署脚本,然后集成到jenkins的Post Steps中,根据实际项目需求,灵活调整脚本,例如添加健康检查、灰度发布等功能,可以搞,小公司可以考虑一下。
写起来简单,用起来嘛,还得自己摸索,肯定会遇到各种各样的问题,慢慢解决就是了,自动化嘛,总比手动强,起码能省下点时间,干点别的,大家都在想,还有没有更简单的方案,比如用docker,可是docker对服务器资源要求高啊,小公司服务器配置本来就低,跑docker有点吃力,而且学习成本也高,要学dockerfile,要学docker-compose,还要学k8s,想想就头大,还是先用这个简单的方法凑合着吧。
总而言之,言而总之,能自动化就别手动,能省时间就省时间,IT人员也要好好爱护自己,别把自己累垮了,身体才是革命的本钱,再说,多出来的时间可以用来学习新技术,提高自己的竞争力,以后跳槽也能多要点工资,是不是这个道理,所有人都在期待,更好的自动化方案。
所以说,持续集成,持续部署,听起来高大上,其实也可以很简单,用简单的工具,解决实际的问题,这才是最重要的,别为了追求完美,反而把自己搞得很累,一切从实际出发,实用才是王道,你说是不是,有时候,简单就是美啊,记住,能偷懒就偷懒。
来源:电子小课堂一点号
