求助, go 端口占用的问题

2023-12-15 11:08:51 +08:00
 c00WKmdje2wZLrSI

环境:ubuntu22.04 go1.20

代码类似于

go func() {
		//开启 websocket 监听
		http.HandleFunc("/", s.handler)
		err := http.ListenAndServe("0.0.0.0:9999", nil)
		if err != nil {
			logger.Log.Fatal(fmt.Sprintf("err=%v", err))
		}
	}()

但是有时候启动会报错,显示err=listen tcp 0.0.0.0:9999: bind: address already in use 然而我使用netstat -tuln |grep 9999时,却显示这个端口没被占用

于是我写一个脚本

#!/bin/bash

while true; do
  netstat -tuln |grep 9999
  sleep 0.1
done

一直开着,再写一个守护脚本当 go 进程结束时自动重启 然后我发现 go 进程因为端口占用问题已经重启了几十次,但是端口扫描的脚本却一次显示端口被占用的情况都没有

但是当我过几个小时再次重启 go 进程时,端口占用问题又消失了 这到底是怎么一回事,而且这情况不是必现的,是偶尔会出现

2247 次点击
所在节点    Go 编程语言
33 条回复
julyclyde
2023-12-15 18:35:55 +08:00
@zhoulq7 iptables 转发的情况并不会发生冲突
只是很单纯的无法生效而已
julyclyde
2023-12-15 18:37:23 +08:00
if err != nil {
logger.Log.Fatal(fmt.Sprintf("err=%v", err))
请你在这里运行一下 netstat -anp
这里应该是能抓到事故现场的
}
pennai
2023-12-16 08:57:24 +08:00
你换个端口号,如果换了端口号还是同样的报错,看看是不是你写的代码有问题,这个函数跑了多次
lifei6671
2023-12-17 11:48:32 +08:00
你可以尝试,只启动端口,不建立客户端连接,这种情况下是不是就不存在端口被占用的情况了。
如果是的话,那么可能是因为服务器端主动断开连接后,这个服务器监听的端口需要等待 2MSL 周期才能再使用。
这个时间会很短,估计在你执行 netstat 命令的时候端口已经释放了。
可以尝试缩短 TIME_WAIT 的时间,或者在关闭服务器之前,将所有客户端都 close 了再关闭服务端。
c00WKmdje2wZLrSI
2023-12-18 01:29:13 +08:00
@julyclyde 感谢,抓到事故现场了,的确有进程监听了那个端口
c00WKmdje2wZLrSI
2023-12-18 02:19:31 +08:00
@julyclyde 说错了,是有进程使用那个端口进行非监听状态的连接,导致我使用 netstat -tuln 找不到进程,而使用 netstat -anp 找到了
julyclyde
2023-12-18 10:20:19 +08:00
@c00WKmdje2wZLrSI 你之前没有加-a 吧
-a 就是搜 LISTEN 的

没明白你说的“非监听状态”是啥意思啊
c00WKmdje2wZLrSI
2023-12-18 10:26:30 +08:00
@julyclyde chatgpt 和我说的,我也不知道那是啥意思
```
netstat -tuln | grep 9999 和 netstat -anp | grep 9999 是两个不同的命令,它们的区别在于使用的参数和显示的信息。

netstat -tuln 命令用于显示所有 TCP 和 UDP 监听的端口。它的参数含义如下:

-t:仅显示 TCP 协议相关的连接。
-u:仅显示 UDP 协议相关的连接。
-l:仅显示监听状态的连接。
-n:以数字形式显示 IP 地址和端口号。
netstat -anp 命令用于显示所有活动的 TCP 和 UDP 连接。它的参数含义如下:

-a:显示所有连接,包括监听和非监听状态的连接。
-n:以数字形式显示 IP 地址和端口号。
-p:显示与连接关联的进程信息。
根据你的描述,可能是因为在使用 netstat -tuln | grep 9999 命令时,没有找到与端口 9999 相关的监听状态的连接,所以没有显示结果。而使用 netstat -anp | grep 9999 命令时,显示了所有活动的连接,包括监听和非监听状态的连接,因此能够发现端口监听情况。
```
julyclyde
2023-12-18 10:27:52 +08:00
@c00WKmdje2wZLrSI GPT 说的和 manpage 也没啥区别啊

那你抓到的现场,它是 ESTABLISHED 还是 LISTEN 呢?
c00WKmdje2wZLrSI
2023-12-18 10:28:19 +08:00
@julyclyde ESTABLISHED
julyclyde
2023-12-18 10:29:26 +08:00
@c00WKmdje2wZLrSI 那我觉得 GPT 肯定不会告诉你 ip_local_port_range 这个词
c00WKmdje2wZLrSI
2023-12-18 11:05:19 +08:00
@julyclyde 是的,不会,而且我发现是另外一个进程和 mysql 通信时临时占用了端口,并且还是随机占用端口,一段时间后又释放了端口,不知道该怎么设置来避免
julyclyde
2023-12-18 20:34:17 +08:00
@c00WKmdje2wZLrSI 那你就搜搜这个词

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1000608

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX