其他分享
首页 > 其他分享> > 卧槽,kill -9 竟然一直都用错了

卧槽,kill -9 竟然一直都用错了

作者:互联网

如果不仔细深究,很难发现这里是有问题的,因为网上介绍kill命令的文章很多,有些是对的,有些是错的,非常容易让我们混淆。

有说进程的:

 

 

 

 

 

也有说线程的:

 

 

 

 

另外,我那篇文章中写到的:

  1. show processlist 命令查出的到底是线程ID,还是进程ID?
  2. mysql是单进程的,kill -9 ID到底杀掉是线程,还是进程?

带着这些疑问,让我们一起开始今天的内容。

一 从mysql说起

我之前的那篇文章主要介绍的是:使用mysql数据库过程中遇到的问题,那就先从mysql说起。

mysql是单进程的

众所周知:mysql是单进程,多线程的。

 

 

 

 

 

 

在5.6以前的版本中,mysql处理连接的方式是One-Connection-Per-Thread,mysql中的一个数据库连接对应一个线程。在高并发的场景下,如果有非常多的连接,需要消耗非常多的内存资源,另外上下文切换也浪费了很多cpu的时间。

 

 

 

 

 

 

 

 

 

在5.6及以后的版本中,mysql处理连接的方式是One-Thread-Per-Connection,mysql中的一个线程对应一个数据库连接。在线程池的实现方案中,线程可以处理的最小单位statment,一个线程可以处理多个数据库连接的请求。

 

 

 

 

 

 

 

 

 

 

show processlist命令

有时我们为了定位mysql的sql问题,特别是报:too many connections问题时,一定会用show processlist命令(mysql会给管理员账号,额外预留一个数据库

连接),查出线程运行情况,数据库连接的状态和有问题的sql语句。例如

 

 

 

 

 

 

 

 

如果是root账号,可以查看所有的线程。

如果是非root账号,只能查看当前登录账号自己的线程,默认只显示前100条记录。如果想查看更多记录,可以使用show full processlist命令。

其实使用show processlist命令是从information_schema.processlist表中查出的结果。

跟使用sql语句:

select * from information_schema.processlist;

效果差不多。

但是,使用sql语句有个好处是可以加where条件,能够进一步过滤数据。

假如查到id=220的那个线程的sql执行非常耗时,接下来怎么办呢?

mysql也有kill命令

既然从上面已经得到了id,接下来的任务就简单了,把那个id对应的线程kill掉就OK了。

但这里的kill命令,并非指linux中我们所熟悉的kill,而是mysql自己的。

什么?mysql也有kill命令?

还真有。

mysql的kill命令分为两种:

  1. kill connection id,它会断开线程的连接,并且停止线程中正在执行的sql语句。它是默认的方式,语法可以简化为:kill id。
  2. kill query id,它会停止线程中正在执行的sql语句,但是不断开线程的连接。

 

再回头看看之前的两个问题:

  1. show processlist 命令查出的到底是线程ID,还是进程ID?
  2. mysql是单进程的,kill -9 ID到底杀掉是线程,还是进程?

show processlist查出的是线程ID。kill ID杀掉的是线程,并且用的mysql自己的kill命令。

另外kill -9 ID这种写法是不对的,mysqlkill命令并不支持-9作为参数。

二 linux如何获取PID?

上面聊完了mysql数据库,接下来,我们聊聊linux

由于linux是开源免费的,而且稳定、性能好,非常适合部署线上服务。

top命令

如果某天,你们公司线上的某个节点,部署了多个服务,其中有一个服务cpu使用率100%,或者内存占用太多了,要如何定位到具体是哪个服务呢?

这时top命令就派上用场了。

 

 

 

 

上图中的%CPU列,表示cpu使用率,图中是无序的。MEM列,表示内存占用情况,也是无序的。

如果要按cpu使用率降序,可以输入大写的:P

如果要按内存占用情况降序,可以输入大写的:M

使用top命令能很快查到,那个服务的cpu使用过高,或者内存占用太多,能查出该服务的pid,也就是进程号

接下来,就可以使用linuxkill命令杀掉该pid对应的异常进程,重启服务,避免该节点资源被耗尽,而影响其他服务。

我之前用这个命令定位过,由于静态资源文件同步的的shell脚本,一次通过的文件数量太多,导致cpu使用率太高的问题。

查看java进程

1.jps

如果是java程序,想找到运行的pid是比较容易的,可以使用:jps命令。

 

 

 

 

这个命令的优点是非常方便得查看pid。缺点是很多关键信息,比如:JVM参数等都没有,不方便排查问题。

2.ps -ef|grep java

如果想查看更多内容,可以使用ps -ef|grep java

 

 

 

 

 

这个命令的优点是除了能查看pid之外,还能查看jdk版本,JVM参数等信息。缺点是如果java服务比较多,显示的内容会很多,不利于查看。

当然linuxps的参数挺多的,具体含义可以参考下面内容:

 

 

 

 

 

 

 

常用的组合参数是:

推荐使用- ef参数。

查看java线程

如果知道了java进程的pid,要查看线程执行情况该怎么办呢?

可以使用jstack pid命令。

 

 

 

 

 

图中的tid就是线程ID,查询结果中还有线程执行状态和部分代码信息,有时候查看某个线程导致cpu使用率过高问题时,使用这个命令特别有效。

我后面会写一个专题讨论cpu使用率过高问题,大家可以期待一下。

需要注意的是线程id,使用kill命令,是杀不掉的。换句话说就是kill杀掉的是进程,而非线程。

三 kill命令的原理

kill命令的执行原理是:会向操作系统内核发送一个信号 和目标进程的PID,然后系统内核根据收到的信号类型,对指定进程进行相应的操作。

语法格式:kill [参数] [进程号]

常用参数:

 

 

 

 

 

可以使用:kill -l 查出所有信号量

 

 

 

 

 

然后根据信号量kill具体pid即可,具体的的语法是:

kill [信号] PID

 

常见信号量可参考如下表格:

 

 

 

 

 

其中kill PID默认使用的是-15

我们平常使用最多的参数是:-3-9-15,那么这三者有啥区别呢?

 

 

这段java代码中增加了ShutdownHook线程,便于在当前应用进程结束时,能够执行一些额外的工作,比如:回收资源。

 

@EnableAsync
@EnableSwagger2
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class})
public class Application {

    /**
     * 程序入口
     *
     * @param args 程序输入参数
     */
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("资源回收");
            }
        });
    }
}

  

当执行kill -9 pid命令时,"资源回收"不会打印。

 

 

 

 

而执行kill -15 pid命令时,"资源回收"才打会印。

 

 

 

建议优先使用kill -15 pid,因为使用它可以回收资源(比如数据库连接)。但是有时候回收资源花费的时间较长,进程可能很长一段时间才会被终止,这是很多程序员不喜欢用-15,而常用-9的原因。

四 kill -9 有时失效了?

你在使用kill -9 pid命令时,有没有出现过杀不掉的情况?

我反正遇到过的。

哪有些情况下杀不掉?

  1. 该进程是僵尸进程,资源已经被释放了,但是没有被父进程释放引用。这种进程,只能等父进程终止后,才能终止。
  2. 进程处于“核心态”,且在等待不可获得的资源。处于核心态的进程忽略所有信号处理,因此对于这些一直处于核心态的进程只能通过重启系统实现。

 

特别预告一下,我后面会写一个专题讨论cpu使用率过高问题,分享我遇到过的多种不同场景,干货满满,小伙伴们可以期待一下。

 

标签:竟然,卧槽,pid,命令,线程,mysql,进程,kill
来源: https://www.cnblogs.com/12lisu/p/14533571.html