解决 进程PID kill不掉 端口关不掉

问题描述

我需要用到3306端口,但我想使用docker安装mysql,但是3306端口一直显示被占用,可能是我在这之前安装的mysql没有删除干净。

一般来说,端口被占用了,直接kill都能停止该端口进程,但是我这里就一直kill不掉。

3306端口kill不掉

从图中可以发现问题的症结所在:从最高层来看,它是由Systemd 系统守护进程调用的。可以简单的理解成:Systemdmysqld的祖先进程。
Systemd是操作系统的第一个进程(PID等于1),其他的进程都是它的子进程;它的设计目标是,为系统的启动和管理提供一套完整的解决方案;Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面;Systemd 可以管理所有系统资源。不同的资源统称为 Unit(单位)。

问题解决:停止父级进程

首先在这我们需要明确,并不是kill进程不成功,事实上,kill进程成功了,所以mysqld结束,PID 5277释放;但是它又被其他服务唤醒,所以mysqld换了一个新的PID 9580 ,仍旧占据着端口号3306

1
2
3
4
5
# pstree -asp PID # 通过子进程查找父级进程
sudo netstat -nlpt | grep 3306 # 查看3306端口占用问题
kill `sudo lsof -t -i:3306` # 杀死占用3306的所有进程
pstree -asp 9617 # 列出9617进程的依赖关系
systemctl stop mysqld # 停止该进程

方法一: lsof

lsof(list open files)是一个列出当前系统打开文件的工具。

lsof 查看端口占用语法格式:

查看端口 lsof

1
2
3
4
5
lsof -i:端口号
# 实例
# lsof -i:8000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nodejs 26993 root 10u IPv4 37999514 0t0 TCP *:8000 (LISTEN)

此时8000端口被NodeJS占用

停止端口进程

1
2
# kill -9 PID
kill -9 26993

image-20220814135035194

更多lsof命令

1
2
3
4
5
6
7
8
9
lsof -i:8080				# 查看8080端口占用
lsof abc.txt # 显示开启文件abc.txt的进程
lsof -c abc # 显示abc进程现在打开的文件
lsof -c -p 1234 # 列出进程号为1234的进程所打开的文件
lsof -g gid # 显示归属gid的进程情况
lsof +d /usr/local/ # 显示目录下被进程开启的文件
lsof +D /usr/local/ # 同上,但是会搜索目录下的目录,时间较长
lsof -d 4 # 显示使用fd为4的进程
lsof -i -U # 显示所有打开的端口和UNIX domain文件

-bash: lsof: 未找到命令

02-lsof-找不到-20230316-465

安装

这是因为系统没有安装到lsof该命令,我们可以安装扩展包。

1
yum -y install lsof

方法二:netstat

查看端口

1
netstat -tunlp | grep 端口号
  • -t (tcp) 仅显示tcp相关选项
  • -u (udp)仅显示udp相关选项
  • -n 拒绝显示别名,能显示数字的全部转化为数字
  • -l 仅列出在Listen(监听)的服务状态
  • -p 显示建立相关链接的程序名

更多命令

1
2
3
netstat -ntlp   				# 查看当前所有tcp端口
netstat -ntulp | grep 80 # 查看所有80端口使用情况
netstat -ntulp | grep 3306 # 查看所有3306端口使用情况

杀掉端口

1
2
# kill -9 PID
kill -9 进程PID

-bash: netstat: 未找到命令

01-netstat找不到-20230316-465

安装

这是因为系统没有安装到net-tools该命令,我们可以安装扩展包。

1
yum -y install net-tools

kill补充

Linux kill 命令用于删除执行中的程序或工作。

kill 可将指定的信息送至程序。预设的信息为 SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用 SIGKILL(9) 信息尝试强制删除程序。程序或工作的编号可利用ps指令或jobs指令查看。

使用语法

1
kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>]

参数说明

  • -l <信息编号>  若不加<信息编号>选项,则-l参数会列出全部的信息名称。
  • -s <信息名称或编号>  指定要送出的信息。
  • [程序]  [程序]可以是程序的PID或是PGID,也可以是工作编号。

使用kill -l命令列出所有可用信号。

最常用的信号是:

1
2
3
- 1 (HUP):重新加载进程。
- 9 (KILL):杀死一个进程。
- 15 (TERM):正常停止一个进程。