改完配置重启服务,报错 Address already in use,8080 到底被谁占了不知道。测试机上一天能遇到两回,翻日志的时间够把服务重启三次。
最快的命令是 ss -lntp,四个参数分别是监听状态、数字端口、TCP、进程信息。配个过滤更省事:ss -lntp | grep 8080,最后那列就是进程名和 PID。
三条命令,看场景挑
- ss -lntp | grep 端口:主流发行版都自带,输出干净,速度最快。
- lsof -i:8080:能看到进程完整路径和启动用户,排查 Java 服务特别好使。
- netstat -tunlp | grep 8080:老系统没装 ss 时的退路,其中 p 参数要有 root 才有输出。
只想确认端口有没有在监听、不看进程,用 ss -lnt 就够,省得每次都加 sudo。反过来,fuser 8080/tcp 直接把占用者的 PID 打在屏幕上,适合写进脚本。
杀之前先确认身份
拿到 PID 别急着 kill -9。先 ps -ef | grep 那个 PID,看清命令行,确认不是数据库,也不是同事正在跑的任务。生产机上误杀一个应用进程,可能连带丢掉没落库的订单。
确认无误用 kill -15 PID,让进程走正常退出流程,释放连接、写完日志。等三五秒还在,再上 kill -9 兜底。直接 -9 会留下锁文件和半截日志,下次启动反而起不来。
几种查不到的情况
容器里执行 ss 看不到宿主机的端口,得在宿主机上查 docker ps 的端口映射,或者进容器的网络命名空间。TIME_WAIT 状态也不算占用,它只是在等超时回收,端口能不能立刻重新绑定,取决于 SO_REUSEADDR 有没有开。
还有一种是自己骗自己:配置里写 8080,启动参数却覆盖成了 8081,你查 8080 当然空空如也,服务其实早跑起来了。
稳妥点,在部署脚本开头加一行端口探测,能用就退出,比出事再翻进程快得多。