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 的原因——一步到位。
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 默认不显示端口信息。你需要这样操作:
- 点击 网络 标签页
- 在进程列表里找到可疑进程
- 双击进程,在弹出的窗口里查看 打开的文件与端口
这里会列出该进程打开的所有端口和网络连接。我一般用它来做「快速定位」——比如发现某个端口被占,但不知道是什么进程,先打开 Activity Monitor 看一眼进程名,再决定要不要用命令行深挖。
4.4 端口监听状态详解
搞清楚了怎么查,我们还得知道查出来的结果是什么意思。端口监听状态,说白了就是端口当前在干什么。
4.4.1 常见状态
| 状态 | 含义 | 常见场景 |
|---|---|---|
| LISTEN | 端口正在监听,等待连接 | Web 服务器、数据库等 |
| ESTABLISHED | 已建立连接,正在通信 | 客户端连接服务器后 |
| TIME_WAIT | 连接已关闭,端口还在等待 | 高并发场景常见 |
| CLOSE_WAIT | 对方关闭连接,本端未关闭 | 程序 bug,未正确关闭 socket |
你想想看,排查端口占用时,我们最关心的是 LISTEN 状态。如果一个端口处于 LISTEN,说明有进程在等着别人连它。如果这个端口不是你预期的服务,那就要小心了——可能是恶意程序,也可能是你忘了关的测试服务。
4.4.2 状态变化流程
我画了一张图,帮你理解端口状态是怎么流转的:
4.5 实战:三步定位端口占用
好了,理论说完了,我们走一遍实战。假设你启动服务时发现 8080 端口被占:
- 第一步:用 lsof 查占用进程
拿到 PID 和进程名。sudo lsof -i :8080 - 第二步:确认进程是否正常
看看这个进程是不是你认识的。如果不认识,用 Activity Monitor 看一眼它的路径。ps aux | grep PID - 第三步:决定处理方式
- 如果是已知进程:检查配置,换个端口或者停掉旧服务
- 如果是未知进程:
sudo kill -9 PID干掉它,然后查一下启动脚本
lsof 是最趁手的工具。图形化工具适合快速定位,netstat 做辅助验证。记住端口状态的含义,你就能快速判断问题出在哪。
嗯,这一章的内容就到这。macOS 的端口排查其实不难,关键是养成习惯——遇到端口被占,先查进程,再决定怎么处理。别一上来就重启机器,那是最后的手段。