ubuntu中“监听(LISTEN)” vs “连接(ESTABLISHED)” 的区别

63 阅读2分钟

image.png

这是一个非常好的问题,我们来深入分析为什么 终止 Nginx 进程后 docker compose up 就能成功,而 Python 进程虽然也在使用 443 端口,却没有阻止 Docker 启动

关键在于: “监听(LISTEN)” vs “连接(ESTABLISHED)” 的区别


🔍 1. 查看 lsof -i :443 输出的两种状态

当你运行 lsof -i :443 时,你会看到两种主要的 状态(STATE)

进程PID状态(STATE)类型
nginx1734LISTEN服务端监听
python2126559, 2487165ESTABLISHED客户端连接

✅ 为什么 Nginx 会阻止 Docker 启动?

  • Nginx 是一个 Web 服务器,它在 0.0.0.0:443 上 监听(LISTEN) ,等待客户端连接。

  • 这意味着它独占了主机的 443 端口,任何其他服务(包括 Docker 容器)都无法再绑定到这个端口。

  • 当你运行 docker compose up,Docker 试图让 dify-nginx 容器也绑定到主机的 443 端口,但系统提示:

    address already in use 因为 Nginx 已经在监听了。

👉 所以:只要有一个进程在 LISTEN 状态占用 443 端口,Docker 就无法绑定。


✅ 为什么 Python 进程不影响 Docker 启动?

  • Python 进程的状态是 ESTABLISHED,表示它是作为客户端,正在与某个服务(比如 Nginx)建立 HTTPS 连接。

  • 它的连接形式通常是:

    深色版本
    python进程:随机端口  →  目标服务器:443
    

    例如:

    深色版本
    192.168.1.100:54321 → 192.168.1.1:443
    
  • 并不监听 443 端口,只是在使用它进行通信。

👉 所以:ESTABLISHED 状态的连接不会阻止其他服务监听 443 端口,因为它只是“访客”,不是“房东”。


🧠 类比理解

  • Nginx (LISTEN) :像一家 24 小时营业的餐厅,门口挂着“欢迎光临”,等着客人进来。
  • Python (ESTABLISHED) :像一个 正在吃饭的顾客,他占了一个座位,但不会阻止新顾客进来。
  • Docker 想启动:就像另一家餐厅想在同一地址开店,但发现“这个门面 already in use”(被第一家餐厅占了),就不能开了。

✅ 验证方法

你可以进一步确认这些 Python 进程的角色:

bash
深色版本
lsof -i :443 | grep python

输出可能类似:

深色版本
python  2126559  user  123u  IPv4  123456789  0t0  TCP  192.168.1.100:54321->192.168.1.1:https (ESTABLISHED)
  • 54321 是本地随机端口(客户端)
  • -> 表示它连接到外部的 :https(即 443)
  • 所以它是出站连接,不是监听。

✅ 总结

进程是否阻止 Docker 绑定 443原因
Nginx (LISTEN)✅ 是它在监听 443 端口,独占了该端口
Python (ESTABLISHED)❌ 否它只是作为客户端连接到 443,不监听

🔑 核心结论
Docker 无法绑定端口,只关心是否有其他进程在 LISTEN 状态占用该端口,而不关心有多少 ESTABLISHED 连接存在。