怪异问题:一个由vscode jupyter插件占用端口引起的问题

前言

  • 今天在运行一个 uwsgi 的python服务时,发现和预想不一致,最开始以为是我的服务有问题,查了好长时间始终不得要领。

  • 表现上看是一个很奇怪的问题:

    ➜ curl http://localhost:9000 curl: (1) Received HTTP/0.9 when not allowed

  • 怎么修改代码都不管用

定位问题过程

  • 最开始以为代码的问题(今天上线时遇到各种问题,正在复盘定位问题),但试了各种修改都不管用,开始怀疑人生的时候,我知道可能不是程序的问题。

  • 于是,我开启了一个最简单的 uwsgi 服务,一样有这种问题。

  • 于是怀疑是不是uwsgi的问题,比如版本之类的、依赖问题啥的,毕竟对这个东西不太熟,但发现我直接使用 python -m http.server 9000 也有这种问题

  • 这就……我怀疑是不是python的问题,于是使用node的http-server也有问题

  • 那会不会是端口的问题,我使用 netstat -nlp tcp | grep 9000 发现没被占,所以不是端口被占的原因(记住我这个结论1)

  • 实在找不到原因了,换个端口试试吧,9001 怎么样,再试试9002 9003…9100,一样的问题,看来真不是端口的问题(记住这个结论2)

  • 我指定端口启动服务器时,也没问题,启动成功了,所以应该不是端口问题(结论3)

  • 实在找不到原因了,吃个饭休息下吧。吃饭时想起,我的知识体系是在本机占的的8888端口,好像没有问题,因为一直在用

  • 吃完回来试试,咦!!!居然是好的,再试试8000也是好的,试试9010,9100……都不行,难道9xxx端口集体罢工了?

找到原因

  • mac下的 netstat -nlp tcp 命令没有发现 9000 被占,但使用 netstat -anlp tcp 命令发现 9000 被占::

netstat -anlp tcp | grep 90 | grep LISTEN
tcp4       0      0  127.0.0.1.9002                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9006                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9003                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9005                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9004                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9006                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9000                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9007                                *.*                                           LISTEN
tcp4       0      0  127.0.0.1.9001                                *.*                                           LISTEN
... ...
  • netstat -anlp tcp 会把不活跃的也列出来,所以这些9xxx都是不活跃的端口(上面结论1被推翻)

  • 原来 9xxx 端口都被占了,所以前面我试了9001 9002 9100 等都没成功很正常,因为这些端口都被占了(上面结论2被推翻)

根因定位

  • 这是什么原因导致的,先用 lsof ,找到进程id:

sudo lsof -i :9004
COMMAND     PID       USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Code\x20H 81199 zhaoweiguo   91u  IPv4 0xebef57f874d0a779      0t0  TCP localhost:52223->localhost:9004 (ESTABLISHED)
python3.8 84139 zhaoweiguo   33u  IPv4 0xebef57f871014e69      0t0  TCP localhost:9004 (LISTEN)
python3.8 84139 zhaoweiguo   66u  IPv4 0xebef57f871095789      0t0  TCP localhost:9004->localhost:52223 (ESTABLISHED)
  • 看下这个进程到底是啥

➜ ps aux | grep 87666
zhaoweiguo       87666   0.0  0.0 35936004   7720   ??  S    Sat10AM   0:00.97 python -m ipykernel_launcher --f=~/Library/Jupyter/runtime/kernel-v2-81196VlEbiD59vsvM.json
  • 原来是 jupyter 的问题,看下vscode 中的jupyter插件,翻文档可知:

默认端口:通常情况下,Jupyter插件会尝试使用默认的端口,比如8888端口。
动态分配端口:如果默认端口被占用,Jupyter插件会尝试动态地选择一个空闲的端口。它会从一系列预定义的端口中选择一个未被占用的端口,通常是从9000到9999之间的端口。
  • vscode 的 jupyter 插件监听的是 localhost的端口,所以启动服务时如果监听 :port 是没有问题(结论3也被推翻)

总结

  • 未来的生活是不确定的

  • 工作遇到奇怪的问题也正常,但总能找到解释的方法