Linux优雅退出问题
问题:Springboot框架开发的项目中会内嵌tomcat容器,在杀死进程的时候tomcat为被正常杀死,导致端口未被释放,第二次启动的时候报端口冲突。
先讲一个基本概念:如何在shell中终止一个后台进程?
kill的作用是向某个指定的进程或进程组发送指定信号,从而结束该进程/进程组。-s选项可以指定要发送的具体信号,如果没有指定,则默认发送SIGTERM(15)信号至指定进程/进程组,若进程没有捕获该信号的逻辑,则SIGTERM的作用是终止进程。

kill pid与kill -9 pid的区别
kill pid的作用是向进程号为pid的进程发送SIGTERM(这是kill默认发送的信号,信号值为15),该信号是一个结束进程的信号且可以被应用程序捕获。若应用程序没有捕获并响应该信号的逻辑代码,则该信号的默认动作是kill掉进程。这是终止指定进程的推荐做法。
kill -9 pid则是向进程号为pid的进程发送SIGKILL(该信号的编号为9),从本文上面的说明可知,SIGKILL既不能被应用程序捕获,也不能被阻塞或忽略,其动作是立即结束指定进程。通俗地说,应用程序根本无法“感知”SIGKILL信号,它在完全无准备的情况下,就被收到SIGKILL信号的操作系统给干掉了,显然,在这种“暴力”情况下,应用程序完全没有释放当前占用资源的机会。事实上,SIGKILL信号是直接发给init进程的,它收到该信号后,负责终止pid指定的进程。关于linux init进程的说明,可以参考这里或这里。在某些情况下(如进程已经hang死,无法响应正常信号),就可以使用kill -9来结束进程。
若通过kill结束的进程是一个创建过子进程的父进程,则其子进程就会成为孤儿进程(Orphan Process),这种情况下,子进程的退出状态就不能再被应用进程捕获(因为作为父进程的应用程序已经不存在了),不过应该不会对整个linux系统产生什么不利影响。
stop() {
echo "Stopping $serviceName"
echo "Testing dir..."
checkDirWritable
if [[ $? -ne ]]; then
echo_failure;
return
fi
[ ! -f $PID_FILE ] && {
echo "Stop: not exist pid file, return directly"
echo_failure;
return
}
PID=`cat $PID_FILE`
RETVAL=$?
[ -z "$PID" ] && {
echo "Stop fail: empty pid file"
echo_failure; #empty pid value"
return ;
}
echo "Searching process with pid: $PID"
ps -p "$PID" >/dev/null >&
if [ $? -eq ]; then
echo "PID($PID) exist, stopping process..."
#用kill命令杀死进程=====================
kill $PID >/dev/null >&
RETVAL=$?
[ $RETVAL -eq ] || {
echo "Stop fail: could not kill process"
echo_failure; # could not kill process
return
}
echo "Stop exiting process success"
else
echo "Cannot find process with pid: $PID"
fi
rm -f $PID_FILE; # Remove control files
rm -f $LOK_FILE
echo_success
return
}
上面也已经提到了:因为springboot项目中会内嵌tomcat容器 在kill进程的时候在被进程捕获后tomcat关闭需要一些时间,如果stop之后不休眠一定时间 有可能会导致tomcat未能正常关闭,导致第二次启动的时候报端口冲突,第二次有Pid但是进程没有成功启动。
所以我们在这里调整stop之后休眠10s在启动start

还有一种情况是:setsockopt中参数SO_REUSEADDR
一般来说,一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。 SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的socket,才可以重复绑定使用。server程序总是应该在调用bind()之前设置SO_REUSEADDR套接字选项。TCP,先调用close()的一方会进入TIME_WAIT状态。
我们知道,在TCP断开链接的时候我们需要四次握手来断开,而且当两端都关闭了read/write通道以后我们还是要等待一个TIME_WAIT时间。
这就是SO_REUSEADDR的作用所在.其实这个选项就是告诉OS如果一个端口处于TIME_WAIT状态, 那么我们就不用等待直接进入使用模式, 不需要继续等待这个时间结束.
那这样我们肯定要问,那为什么我们需要有这个TIME_WAIT时间啊?
看看TCP/IP协议组我们就知道,这样做是为了让在网络中残余的TCP包消失, 也就是说, 如果我们没有等到这个时间就让OS把这个端口释放给其他的进程使用,别的进程很有可能就会收到上一个会话的残余TCP包,这样就会出现一系列的不可预知的错误.
Linux优雅退出问题的更多相关文章
- 正确使用‘trap指令’实现Docker优雅退出
一般应用(比如mariadb)都会有一个退出命令,用户使用类似systemctl stop ****.service方法,停止其服务时,systemd会调用其配置文件注册的退出命令,该命令执行清理资源 ...
- .NET Worker Service 如何优雅退出
上一篇文章中我们了解了 .NET Worker Service 的入门知识[1],今天我们接着介绍一下如何优雅地关闭和退出 Worker Service. Worker 类 从上一篇文章中,我们已经知 ...
- .NET Worker Service 作为 Windows 服务运行及优雅退出改进
上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录,今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行. 我曾经在前面一篇文章 ...
- 优雅退出在Golang中的实现
背景 为什么需要优雅关停 在Linux下运行我们的go程序,通常有这样2种方式: 前台启动.打开终端,在终端中直接启动某个进程,此时终端被阻塞,按CTRL+C退出程序,可以输入其他命令,关闭终端后程序 ...
- TODO:Golang Linux进程退出说明
TODO:Golang Linux进程退出说明 Golang使用os.Exit(code)进程退出导致当前程序退出并返回给定的状态代码.传统上,code代码为零表示成功退出,非零错误退出. sysca ...
- Linux 进程退出后自动启动
/********************************************************************** * Linux 进程退出后自动启动 * 说明: * 在系 ...
- Node 出现 uncaughtException 之后的优雅退出方案
Node 的异步特性是它最大的魅力,但是在带来便利的同时也带来了不少麻烦和坑,错误捕获就是一个.由于 Node 的异步特性,导致我们无法使用 try/catch 来捕获回调函数中的异常,例如: try ...
- NodeJS服务器退出:完成任务,优雅退出
上一篇文章,我们通过一个简单的例子,学习了NodeJS中对客户端的请求(request)对象的解析和处理,整个文件共享的功能已经完成.但是,纵观整个过程,还有两个地方明显需要改进: 首先,不能共享完毕 ...
- Python3.x:Linux下退出python命令行
Python3.x:Linux下退出python命令行 退出命令: quit() #或者 exit() #或者 Ctrl-D
随机推荐
- Cg入门14:Vertex Shader - 几何变换 —顶点扭曲
mul (UNITY_MATRIX_MVP,upPos): 參数说明 由第一个參数UNITY_MATRIX_MVP 矩阵去影响第二个參数upPos向量(或者矩阵) Shader "Sbin/ ...
- jQuery实现tag便签去重效果的方法
本文实例讲述了jQuery实现tag便签去重效果的方法.分享给大家供大家参考.具体实现方法如下: html代码如下: <head><script type="text/ja ...
- Struts2_day01--Struts2的核心配置文件_常量配置_分模块开发_Action编写方式
Struts2的核心配置文件 1 名称和位置固定的 2 在配置文件中主要三个标签 package.action.result,标签里面的属性 标签package 1 类似于代码包,区别不同的actio ...
- SDL 威胁建模工具入门 threat modeling tool
http://msdn.microsoft.com/zh-cn/magazine/dd347831.aspx threat modeling tool 威胁建模工具 minifuzz 文件模糊工具 c ...
- [Domino]从嵌入另一个数据库嵌入的Embedded View无法正常显示,提示unable to lauch
发现问题 1. 项目中需要在一个数据库中插入另一个数据库的Embedded View,使用起来十分费劲,在选择数据库的下拉菜单中经常会找不到目标数据库: 2. 在做日文版的时候,从workbench导 ...
- SaltStack配置管理-LAMP状态设计
上一篇:SaltStack之Salt-ssh 配置文件模板 apache: pkg.installed: - name: httpd service.running: - name: httpd /e ...
- Exchange Database Status(Copy Status ,Content Index State,QueueLength,Move Status...)
Copy Status Description Mounted The active copy is online and accepting client connections. Only the ...
- HDU_5512_Pagodas
Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Nagle's Algorithm and TCP_NODELAY
w非全尺寸分组的发送条件 HTTP The Definitive Guide TCP has a data stream interface that permits applications to ...
- mysql数据库基本知识,简单框架
https://www.cnblogs.com/geaozhang/p/7347950.html