起服务报 EADDRINUSE 端口被占用,我重启了三次电脑

前天晚上我在弄一个大二闲下来想练手的小东西,一个本地跑的待办清单页面,前端后端都在我自己这台电脑上。写完一段想看下效果,就在终端敲了启动命令,回车。

然后它报错了。

报错不是那种一眼能看懂的类型。终端里滚出来一大串,我能认出来的只有最后那行的端口号 8080,旁边那个 EADDRINUSE 我当时完全不知道是什么东西。我第一反应是电脑卡住了。

于是我把服务关掉,重新敲了一遍命令。

还是这个错。

我当时也没多想,觉得可能是刚才那次没关干净,那重启一下电脑就好了,重启完什么残留都没了。

坐在那儿等开机进度条慢慢转完,期间一直盯着屏幕,心里想这下总可以了。开机之后我又把服务跑起来,能跑了。

本来以为这就翻篇。结果过了两天又碰上同样的事,我又重启了一次。等到第三次的时候我才停下来问自己,我这两天到底在干嘛。

```bash

$ npm run dev

> dev

> node server.js

Error: listen EADDRINUSE: address already in use :::8080

    at Server.setupListenHandle [as _listen2] (net.js:1313:16)

```

## 那个 8080 到底是什么

后来老老实实去翻了文档和别人的踩坑帖。道理其实特别简单,8080 就是一个门牌号,你起服务等于在这条街上占了个门面,门面已经有人了,你当然进不去。报错说的就是这个门牌号被占了。

问题是我根本不知道怎么查是谁占的。这一步我之前完全跳过,一出错就直接重启。

macOS 和 Linux 上可以这样看:

```bash

# macOS / Linux:谁占着 8080 这条街

lsof -i :8080

# Linux 上也可以,看清楚是哪个进程

ss -lntp | grep 8080

# Windows 换成这个,最后一列就是 PID,我盯了半天才认出来

netstat -ano | findstr :8080

```

`lsof -i :8080` 会把占用这个端口的进程列出来。我第一次看的时候,盯着其中一列数字愣了半天,后来才知道那是 PID,进程号。帖子里说拿这个号去把进程结束掉,我照着敲了一遍才慢慢明白它在干什么。

这里有个坑,看到 PID 别急着杀。先看那一行最前面写的进程名是什么。我那次看到的进程名,就是我自己前一次跑起来、根本没关掉的服务。

## 我以为我关掉了

那为什么我明明关了它还在?因为按 Ctrl+C 之后终端是退出来了,但服务其实是包在一层启动脚本里跑的,我结束掉的只是外面那层,真正占端口的那个小进程还在后台待着。用 npm run dev 起服务经常是这样。类似的情况还有你之前拿 nohup 或者加个 & 把它挂在后台,关窗口的时候把它忘了。

确认是自己留下的,就可以结束了。macOS 和 Linux 是 kill 后面跟 PID,它要是不退,就 kill -9,这个是强制的。Windows 上换成 taskkill。

```bash

# macOS / Linux,先温柔一点,PID 换成你查到的那个

kill 12345

# 它赖着不走,再强制

kill -9 12345

# Windows

taskkill /PID 12345 /F

```

如果占端口的不是我自己的东西呢。有时候是另一个项目也在用这个端口,甚至是不认识的系统进程。这种就别去动它,改自己项目的端口更省事,8080 改成 8081,跑起来就行,没必要为了一个数字去跟别人的进程较劲。

话说回来,重启电脑确实有用,进程跟着系统一起没了,端口自然就空出来。它能把这一次糊弄过去,下次还是会撞上。换个端口就能跑,那为什么还要花时间去查?因为在别人电脑上,在 CI 里,在服务器上,你没法重启,只能知道怎么办。

现在我再起服务之前,会先看一眼那个端口有没有人。也不是每次都查,就是报过一次错之后,心里大概有个数了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容