记一次生产发版时SpringBoot服务停用启用的问题
近期项目交接,接手了个SpringBoot项目。生产环境里,jar包是通过软链接做成linux服务来启动和停用。
然而,每次通过jenkins构建发版,项目构建完毕,还要手动再去重启服务。
听交接的同事说,可能是有一个钩子阻止服务停用了。
但是,我还是有点纳闷的,既然阻止了服务停用,按道理服务是还能再运行的,不可能构建完了服务就不可用,然后还要手动重启。
随后,我就开始了漫长的搜索……最后还是找到答案了。
步骤重现:
jenkins构建项目,执行脚本,停用服务
service crm-base stop
等了大约一分钟,窗口返回:
Unable to kill process [*****]
脚本执行完停止命令,随后执行启动命令
Unable to kill process [*****]
结果提示,服务正在运行。
Already running [*****]
然而,过了一会儿,去访问服务接口时,服务没有响应了。去查Eureka,微服务的状态此时是Down。
查服务的状态
service crm-base status
结果服务是没有启动的
Not running
显然,执行了服务停止的命令是有效的,感觉是一段时间内服务没有停下来而提示“Unable to kill process”。
接下来,在看到了SpringBoot的内嵌启动脚本源码,也印证了我的想法。
stop() {
working_dir=$(dirname "$jarfile")
pushd "$working_dir" > /dev/null
[[ -f $pid_file ]] || { echoYellow "Not running (pidfile not found)"; return ; }
pid=$(cat "$pid_file")
isRunning "$pid" || { echoYellow "Not running (process ${pid}). Removing stale pid file."; rm -f "$pid_file"; return ; }
do_stop "$pid" "$pid_file"
}
do_stop() {
kill "$1" &> /dev/null || { echoRed "Unable to kill process $1"; return ; }
for i in $(seq $STOP_WAIT_TIME); do
isRunning "$1" || { echoGreen "Stopped [$1]"; rm -f "$2"; return ; }
[[ $i -eq STOP_WAIT_TIME/ ]] && kill "$1" &> /dev/null
sleep
done
echoRed "Unable to kill process $1";
return ;
}
可以看到,执行停止方法,本质是做kill操作。方法内有一个for循环,从1遍历到$STOP_WAIT_TIME,每次循环休眠1秒。提示“Unable to kill process”有两处,一处是for循环前,一次是for循环后。
至于$STOP_WAIT_TIME的默认值是多少,我们用Ctrl+F搜脚本
# Initialize stop wait time if not provided by the config file
[[ -z "$STOP_WAIT_TIME" ]] && STOP_WAIT_TIME="{{stopWaitTime:60}}"
可以看到,如果没有配置设置停止等待时间,默认就是60秒。正好印证了这一问题,服务停止约一分钟就提示杀进程失败,而实际上是进程还在处理,需要等待,并非是钩子的问题。
解决方法:
在jar包路径下加jar包同名的配置文件(e.g.:jar包文件名为crm-base.jar,则添加配置的文件名称为crm-base.conf),在配置中调整停止等待时间为120秒
STOP_WAIT_TIME=
再次尝试用jenkins构建,服务终于能顺利重启了。
开始关闭服务
-------------
Stopped []
-------------
开始启动服务
Started []
所以,遇到问题的时候,百度是能短时间解决同类问题,但是找不到解决方法的,还是通过阅读源码最可靠。
参考文档:
[1]. https://github.com/spring-projects/spring-boot/issues/4369
[2]. https://github.com/spring-projects/spring-boot/issues/10159
[3]. https://www.jianshu.com/p/e21b95006371
[4]. https://www.jianshu.com/p/1414dc49d3a9
记一次生产发版时SpringBoot服务停用启用的问题的更多相关文章
- vs 发版时,在发版的文件夹中,找不到应该有的某个文件
检查:VS中,这个文件右击属性,查看生成操作.如果是“无”,改为“内容”.再重新发布就没问题了. 想看发版出来的内容包括哪些,可以从“发布”--“应用程序文件”查看
- 用node.js写一个jenkins发版脚本
背景 每次到网页里手动发版有点烦,写个脚本来提高开发效率. CFG 在 jenkins 设置里获取 API TOKEN. 把 host 和账号密码拼接起来就可以通过鉴权. const token = ...
- java生产环境增量发版陷阱【原】
前言 在生产环境,我们为了降低发版风险,一般都只做增量发布,不做全量发布. 除非项目只有一到两人开发,对时间线和代码脉络结构一清二楚,才可全量发布. 然而增量发布也是有一定隐藏陷阱在里面的,以下就是笔 ...
- CICD自动化发版系统设计简介
第一篇. 版本迭代是每一个互联网公司必须经历的,尤其是中小型公司,相信不少人踩到过很多坑.接下来的一系列文章将介绍我设计的自动化发版系统! 很多公司没有把配置独立出去,代码的构建.发版通过一个Jenk ...
- 【解决方案】SpringCloud项目优雅发版、部署
背景 SpringCloud分布式项目,部署在多个节点上.一般的发版方式是,使用Kill -15 pid,逐一地关闭.部署.重启. 但中间涉及到一个问题,当执行kill命令时,服务虽然关闭,但Eure ...
- CI/CD自动化发版系统设计简介
转载自:https://www.cnblogs.com/wellful/archive/2004/01/13/10604151.html 版本迭代是每一个互联网公司必须经历的,尤其是中小型公司,相信不 ...
- 使用 shell 脚本自动获取发版指标数据
问题背景 大一点的公司都会建立一套规章流程来避免低级错误,例如合入代码前必需经过同行评审:上线前必需提测且通过 QA 验证:全量前必需经过 1%.5%.10%.20%.50% 的灰度过程.尤其是最后一 ...
- Jenkins日常运维笔记-重启数据覆盖问题、迁移、基于java代码发版(maven构建)
之前在公司机房部署了一套jenkins环境,现需要迁移至IDC机房服务器上,迁移过程中记录了一些细节:1)jenkins默认的主目录放在当前用户家目录路径下的.jenkins目录中.如jenkins使 ...
- 阿里云移动研发平台 EMAS 助力银行业打造测试中台,提升发版效能
随着移动互联网的发展,手机银行凭借低成本.操作简单.不受时间空间约束等优势,正逐步替代传统的网银交易方式.越来越多的银行开始了“业务移动化”转型之路,“手机APP”已经成为企业价值传递和关系维护的关键 ...
随机推荐
- springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1.1 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeEx ...
- MVC FormCollection 无法获取值的问题
把action定义为[HttpPost],并且ajax.beginform中ajaxoption中定义为Post,在提交表单时就可以获取FormCollection的值了.httpGet或者后台不定 ...
- OpenGLES.gpus_ReturnNotPermittedKillClient
在iOS中,使用OpenGLES不当引起的crash:“gpus_ReturnNotPermittedKillClient” https://developer.apple.com/library/i ...
- Codeforces Recycling Bottles 模拟
C. Recycling Bottles time limit per test: 2 seconds memory limit per test: 256 megabytes input: stan ...
- 谈谈我对Ui设计师的一些观点
做ui设计师3年多了,对ui设计师在工作中也了解了许多. 作为UI设计师,在工作中需要清楚了解设计的目的,尤其是你做的不是大众化产品,不能以个人认知.很强的主题性来确定. 例如针对儿童人群的app时, ...
- Debian 利用 iso 镜像完全离线更新 apt-cdrom
1 目的 在日常的 linux 服务器管理中,出于某些考虑,服务器要求与 Internet 完全隔离. 这使得我们对系统的更新和软件包的升级感到无比头疼. 下面介绍的这种方法,采用 ISO 文件,进行 ...
- [SoapUI] 设置最大等待时间,不断重复的去发送一个request,每次从response中获取一个status,直到这个status从一种状态变成另外一种状态
import com.eviware.soapui.support.GroovyUtils def groovyUtils = new GroovyUtils( context ) def holde ...
- [Jmeter]通过批处理调用java,java从CSV动态读取登录的用户名和密码,并将其作为参数组合成字符串,写入外部.bat文件,然后通过Java执行这个外部批处理文件
问题1:怎样通过批处理调用java代码? 问题2:怎样通过java从CSV文件获取到用户名和密码存入变量? 问题3:怎样将获取到的用户名和密码组合成字符串,写入外部批处理文件? 问题4:怎样在批处理文 ...
- Mina 系列(四)之KeepAliveFilter -- 心跳检测
Mina 系列(四)之KeepAliveFilter -- 心跳检测 摘要: 心跳协议,对基于CS模式的系统开发来说是一种比较常见与有效的连接检测方式,最近在用MINA框架,原本自己写了一个心跳协议实 ...
- jsp札记
日期格式化 <s:date name="creaetime" format="yyyy-MM-dd HH:mm:ss" /> <base hr ...