4. macOS 系统排查:lsof、netstat 与 Activity Monitor

macOS 的端口排查,说实话跟 Linux 有点像,但又有不少坑。我最早从 Linux 转 macOS 时,就吃过不少亏——明明 netstat 打出来了,却看不到进程 PID,急得直挠头。后来才搞明白,macOS 的 netstat 是 BSD 系的,参数习惯完全不同。

这一章,我把 macOS 上最常用的三套排查手段都捋一遍。我个人习惯是:先图形化看一眼,再用命令行深挖。你跟着走一遍,基本能覆盖 90% 的场景。

4.1 lsof:我的首选武器

lsof 全称是 List Open Files。在 macOS 上,它比 netstat 好用得多。为什么?因为它能直接告诉你哪个进程在占用端口,不用再额外做一次 PID 反查。

4.1.1 查端口监听

最常用的命令就这一条:

sudo lsof -i :端口号

比如我想查 8080 端口:

sudo lsof -i :8080

输出大概长这样:

COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    12345  zhangsan  123u  IPv4 0x123456789abcdef      0t0  TCP *:8080 (LISTEN)

看到 (LISTEN) 了吗?这就是我们要找的监听状态。我一般直接看 COMMAND 和 PID 两列,就知道是谁在占坑了。

小技巧: 不加 sudo 有时看不到系统进程的端口信息。我建议你养成习惯,查端口时直接加 sudo,省得漏掉关键信息。

4.1.2 查所有监听端口

如果你想看看机器上到底有哪些端口在监听:

sudo lsof -iTCP -sTCP:LISTEN

这条命令会列出所有 TCP 监听端口。我个人经常用它来做「端口清点」,特别是刚接手一台新 Mac 时,先跑一遍看看有没有奇怪的服务在跑。

4.1.3 根据 PID 反查端口

有时候你发现某个进程很可疑,想看看它占了多少端口:

sudo lsof -i -p PID

比如:

sudo lsof -i -p 12345

输出会列出该进程打开的所有网络连接,包括监听端口和已建立的连接。嗯,这里要注意——如果进程开了很多连接,输出会很长,你可以配合 grep 过滤。

4.2 netstat:备胎但也要会用

macOS 自带的 netstat 是 BSD 版本,跟 Linux 的 netstat 参数差异很大。我第一次用 netstat -tlnp 时,直接报错——macOS 根本不认 -p 参数。

4.2.1 查监听端口

正确的姿势是:

netstat -an | grep LISTEN

或者更精确一点:

netstat -anv | grep LISTEN

-v 参数会显示更多信息,包括发送队列和接收队列的大小。我在排查连接堆积问题时,经常用这个。

4.2.2 查具体端口

netstat -an | grep 8080

输出示例:

tcp4  0  0  *.8080    *.*    LISTEN

看到了吗?macOS 的 netstat 默认不显示 PID。你得配合 lsof 或者 ps 才能找到进程。这也是为什么我更喜欢 lsof 的原因——一步到位。

避坑指南: 我曾经在 macOS 上用 netstat -p tcp 想过滤 TCP 协议,结果发现它根本不支持 -p 参数。正确的做法是用 netstat -p tcp 吗?不对,macOS 的 -p 是 -protocol 的缩写,用法是 netstat -p tcp 确实可以,但输出格式跟 Linux 完全不同。我建议你直接记住:macOS 上查端口用 lsof,netstat 只做辅助验证。

4.3 Activity Monitor:图形化排查

说实话,很多运维同行觉得图形化工具不够「专业」。但我不这么看。有时候你只是想快速确认一下某个端口是不是被占着,打开 Activity Monitor 点几下,比敲命令快多了。

4.3.1 打开方式

  • 在 应用程序 > 实用工具 里找到 Activity Monitor
  • 或者直接用 Spotlight(Cmd+Space)搜索「Activity Monitor」

4.3.2 查端口占用

Activity Monitor 默认不显示端口信息。你需要这样操作:

  1. 点击 网络 标签页
  2. 在进程列表里找到可疑进程
  3. 双击进程,在弹出的窗口里查看 打开的文件与端口

这里会列出该进程打开的所有端口和网络连接。我一般用它来做「快速定位」——比如发现某个端口被占,但不知道是什么进程,先打开 Activity Monitor 看一眼进程名,再决定要不要用命令行深挖。

我的习惯: 图形化工具适合「看一眼就走」的场景。如果你需要写报告或者做自动化排查,还是老老实实用命令行。但如果你只是自己调试,Activity Monitor 完全够用。

4.4 端口监听状态详解

搞清楚了怎么查,我们还得知道查出来的结果是什么意思。端口监听状态,说白了就是端口当前在干什么。

4.4.1 常见状态

状态 含义 常见场景
LISTEN 端口正在监听,等待连接 Web 服务器、数据库等
ESTABLISHED 已建立连接,正在通信 客户端连接服务器后
TIME_WAIT 连接已关闭,端口还在等待 高并发场景常见
CLOSE_WAIT 对方关闭连接,本端未关闭 程序 bug,未正确关闭 socket

你想想看,排查端口占用时,我们最关心的是 LISTEN 状态。如果一个端口处于 LISTEN,说明有进程在等着别人连它。如果这个端口不是你预期的服务,那就要小心了——可能是恶意程序,也可能是你忘了关的测试服务。

4.4.2 状态变化流程

我画了一张图,帮你理解端口状态是怎么流转的:

TCP 端口状态流转图 CLOSED LISTEN ESTABLISHED TIME_WAIT CLOSE_WAIT bind() accept() close() 对方关闭 超时后 排查端口占用时,重点关注 LISTEN 状态;CLOSE_WAIT 和 TIME_WAIT 过多说明程序可能有 bug

4.5 实战:三步定位端口占用

好了,理论说完了,我们走一遍实战。假设你启动服务时发现 8080 端口被占:

  1. 第一步:用 lsof 查占用进程
    sudo lsof -i :8080
    拿到 PID 和进程名。
  2. 第二步:确认进程是否正常
    ps aux | grep PID
    看看这个进程是不是你认识的。如果不认识,用 Activity Monitor 看一眼它的路径。
  3. 第三步:决定处理方式
    • 如果是已知进程:检查配置,换个端口或者停掉旧服务
    • 如果是未知进程:sudo kill -9 PID 干掉它,然后查一下启动脚本
核心要点: macOS 上排查端口占用,lsof 是最趁手的工具。图形化工具适合快速定位,netstat 做辅助验证。记住端口状态的含义,你就能快速判断问题出在哪。

嗯,这一章的内容就到这。macOS 的端口排查其实不难,关键是养成习惯——遇到端口被占,先查进程,再决定怎么处理。别一上来就重启机器,那是最后的手段。