求助, 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 进程时,端口占用问题又消失了 这到底是怎么一回事,而且这情况不是必现的,是偶尔会出现

2249 次点击
所在节点    Go 编程语言
33 条回复
c00WKmdje2wZLrSI
2023-12-15 11:20:11 +08:00
各位大哥有没有解决的思路可以说一说
misaka19000
2023-12-15 11:35:04 +08:00
写个其它语言的代码看看能不能监听这个端口
daniel8642
2023-12-15 11:51:54 +08:00
0.0.0.0:9999
可以试试填写一下需要绑定到的网卡 ip 地址。
之前在 wsl2 上出现绑定之后访问不了,就是通过填写 ip 解决的。
imherer
2023-12-15 12:00:13 +08:00
会不会是你这个函数被多次调用了?
c00WKmdje2wZLrSI
2023-12-15 12:04:05 +08:00
@daniel8642
@imherer

主要是这个是偶现的,而且我端口扫描脚本显示进程启动时它所需要的端口没被占用
sky96111
2023-12-15 12:21:01 +08:00
https://zhaoji.wang/solve-the-problem-of-windows-10-ports-being-randomly-reserved-occupied-by-hyper-v/
看看是不是这个问题。我经常遇到
c00WKmdje2wZLrSI
2023-12-15 12:33:18 +08:00
@sky96111 不是,我是腾讯云的服务器,ubuntu22.04, 而且主要是我扫描了端口,显示未占用
zhoulq7
2023-12-15 13:16:10 +08:00
如果用了 iptables 做的端口流量转发是不能通过 netstat 查到这个被占用的端口的
sky96111
2023-12-15 13:54:49 +08:00
@c00WKmdje2wZLrSI Linux 啊,那你用 lsof -i :端口号查一下。被内核占用的端口直接是看不到的
barathrum
2023-12-15 14:11:32 +08:00
可能是 socket 还没回收,关应用的时候如果正好有链接要等 60 秒 保证被回收,没有链接的话就能直接用了。
ss 的时候去掉 l 再看看可能发现有正在关闭状态的链接。
c00WKmdje2wZLrSI
2023-12-15 14:17:07 +08:00
@zhoulq7 systemctl status firewalld 和 systemctl status firewalld 显示没这两个软件
c00WKmdje2wZLrSI
2023-12-15 14:18:41 +08:00
@barathrum 我换了端口后,扫描新端口没被占用,但是新端口第一次启动也有几率出现说端口被占用
longbowape
2023-12-15 14:22:14 +08:00
需要给端口设置 SO_REUSEADDR ,否则即使进程推出了也会显示一段时间的被占用。
Pythoner666666
2023-12-15 14:22:44 +08:00
云服务器有一些 厂商自带的扫描或者监控软件 他们可能是定时启动 端口也是 9999 ,所以可能刚好跟你冲突了。仅提供一个思路,不一定对哈。
barathrum
2023-12-15 14:26:49 +08:00
你的监控脚本换一下参数,比如 netstat -neoap 啥的,端口不一定是 listen 的。
lsk569937453
2023-12-15 14:33:33 +08:00
https://groups.google.com/g/golang-nuts/c/nUMvimzSZvk
不知道是不是和这个有关系,用 go build 后的二进制包启动,而不是用 go run 启动进程。
liarsa
2023-12-15 14:40:32 +08:00
我也碰到过,但没细研究,过一会它自己就好了
c00WKmdje2wZLrSI
2023-12-15 15:00:00 +08:00
@lsk569937453 我使用的就是 go build 的二进制包启动的
pkoukk
2023-12-15 18:03:48 +08:00
简单啊,你测试下换几个端口,如果还有问题就是你代码写的问题
如果没问题就是你环境的问题
mangoDB
2023-12-15 18:27:24 +08:00
netstat -n | grep TIME_WAIT

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

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

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

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

© 2021 V2EX