一、kill -9 pid
杀进程的弊端
kill 可将指定的信息送至程序。预设信息为 SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用 SIGKILL(9) 信息尝试强制删除程序。简言之,就是用来杀死 linux 中的进程的。
Perl 大牛 Randal Schwartz 这样描述过,不要使用kill -9
。它没有给进程留下善后的机会:
1️⃣关闭 socket 连接。
2️⃣清理临时文件。
3️⃣把自己将要被销毁的消息通知给子进程。
4️⃣重置终止状态。
kill -9 pid 带来的问题
如果用了kill -9
,就意味着用收割机来修剪花盆里的花,换句话说,就是杀鸡用了牛刀。进程没有机会完成清理工作,会留下一些不完整的文件和状态。下次系统重启时会带来很多麻烦。
例:转账功能,在给两个账户进行加钱扣钱的时候突然断电了。对于 InnoDB 存储引擎来说,没有什么损失,因为它支持事务,但是对于 MyISAM 引擎来说那简直就是灾难,为什么?假如给 A 账户扣了钱,现在需要将 B 账户加钱,此时停电,就会造成,A 的钱被扣了,但是 B 没有拿到这笔钱,这在生产环境是绝对不允许的,kill -9 相当于突然断电的效果。
当然,像转账这种,肯定不用 MyISAM 引擎,但是如今分布式跨服务转账已是常见,此时如果使用kill -9
停止服务,那就不是事务能保证数据的准确性了。世界上没有绝对安全的系统或者架构,即便分布式事务也是一样存在问题,概率很小,一旦发生,损失有可能是无法弥补的,所以一定不能使用kill -9
去停止服务。
在 MyISAM 引擎中表现的更明显,比如用户的信息由两张表维护,管理员修改用户信息的时候需要修改两张表,但由于kill -9
暴力结束项目,导致只修改成功了一张表,这也会导致数据的不一致性,这是小事,因为大不了再修改一次,但是金钱、合同这些重要的信息如果由于暴力删除导致错乱,甚至比删库跑路还严重,至少删库还能恢复。
二、SIGKILL 和 SIGTERM
执行kill -9
时,系统会发 SIGKILL 信号给进程。而执行kill -15
命令时,系统会发 SIGTERM 的信号给进程。
1️⃣收到 SIGKILL 的信号,进程立即终止,该信号不能被捕获或忽略,并不执行任何清理文件步骤。非常残酷和决绝。
2️⃣收到 SIGTERM 的信号,会导致进程的终止,但是不同于SIGKILL,它可以被捕获和解释(或忽略)。 有点像:温柔的问一句进程,终止你可好?这样可以清理文件并关闭。
事实上,正常关机的时候,大部分系统都会发 SIGTERM 给所有不是一定要断电的进程,等待几秒,然后发出 SIGKILL 强行终止仍旧存在的进程。
三、kill -9
之前能做什么
当输入 kill 的时候,默认发送的就是 -15,发送 **SIGTERM ** 信号,以便为目标进程提供自我清理的机会。如果进程被卡住,比较好的一些方法是可以使用strace、truss、ltrace 或 gdb
来查看进程为什么被卡住,此外pstack
也可以协助排查。
在kill -9
痛下杀手之前,一般情况下,可以发送 15(SIGTERM),查看状态。等待一会儿,如果不起作用,发送 2(SIGINT);如果还不起作用,发送 1(SIGHUP);如果不成功,删除二进制文件,因为程序不是在正常运行。
四、什么时候应该用kill -9
kill -9
是不得已而为之的手段,尽量不要用在生产上,特别是像mount
这样的进程上,除非再也不想用那个进程关联的程序、数据库、磁盘、文件。
五、应该怎么结束项目
其实 Java 提供了结束项目的功能,比如:Tomcat 可以使用shutdown.bat/shutdown.sh
进行优雅结束。
什么叫优雅结束?
- 停止接收请求和内部线程。
- 判断是否有线程正在执行。
- 等待正在执行的线程执行完毕。
- 停止容器。
以上四步才是正常的结束流程。
网友评论