求助, go 端口占用的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
c00WKmdje2wZLrSI
V2EX    Go 编程语言

求助, go 端口占用的问题

  •  
  •   c00WKmdje2wZLrSI 2023-12-15 11:08:51 +08:00 2671 次点击
    这是一个创建于 674 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    主要是这个是偶现的,而且我端口扫描脚本显示进程启动时它所需要的端口没被占用
    sky96111
        6
    sky96111  
       2023-12-15 12:21:01 +08:00 via Android
    https://zhaoji.wang/solve-the-problem-of-windows-10-ports-being-randomly-reserved-occupied-by-hyper-v/
    看看是不是这个问题。我经常遇到
    c00WKmdje2wZLrSI
        7
    c00WKmdje2wZLrSI  
    OP
       2023-12-15 12:33:18 +08:00
    @sky96111 不是,我是腾讯云的服务器,ubuntu22.04, 而且主要是我扫描了端口,显示未占用
    zhoulq7
        8
    zhoulq7  
       2023-12-15 13:16:10 +08:00
    如果用了 iptables 做的端口流量转发是不能通过 netstat 查到这个被占用的端口的
    sky96111
        9
    sky96111  
       2023-12-15 13:54:49 +08:00 via Android
    @c00WKmdje2wZLrSI Linux 啊,那你用 lsof -i :端口号查一下。被内核占用的端口直接是看不到的
    barathrum
        10
    barathrum  
       2023-12-15 14:11:32 +08:00
    可能是 socket 还没回收,关应用的时候如果正好有链接要等 60 秒 保证被回收,没有链接的话就能直接用了。
    ss 的时候去掉 l 再看看可能发现有正在关闭状态的链接。
    c00WKmdje2wZLrSI
        11
    c00WKmdje2wZLrSI  
    OP
       2023-12-15 14:17:07 +08:00
    @zhoulq7 systemctl status firewalld 和 systemctl status firewalld 显示没这两个软件
    c00WKmdje2wZLrSI
        12
    c00WKmdje2wZLrSI  
    OP
       2023-12-15 14:18:41 +08:00
    @barathrum 我换了端口后,扫描新端口没被占用,但是新端口第一次启动也有几率出现说端口被占用
    longbowape
        13
    longbowape  
       2023-12-15 14:22:14 +08:00
    需要给端口设置 SO_REUSEADDR ,否则即使进程推出了也会显示一段时间的被占用。
    Pythoner666666
        14
    Pythoner666666  
       2023-12-15 14:22:44 +08:00
    云服务器有一些 厂商自带的扫描或者监控软件 他们可能是定时启动 端口也是 9999 ,所以可能刚好跟你冲突了。仅提供一个思路,不一定对哈。
    barathrum
        15
    barathrum  
       2023-12-15 14:26:49 +08:00
    你的监控脚本换一下参数,比如 netstat -neoap 啥的,端口不一定是 listen 的。
    lsk569937453
        16
    lsk569937453  
       2023-12-15 14:33:33 +08:00
    https://groups.google.com/g/golang-nuts/c/nUMvimzSZvk
    不知道是不是和这个有关系,用 go build 后的二进制包启动,而不是用 go run 启动进程。
    liarsa
        17
    liarsa  
       2023-12-15 14:40:32 +08:00
    我也碰到过,但没细研究,过一会它自己就好了
    c00WKmdje2wZLrSI
        18
    c00WKmdje2wZLrSI  
    OP
       2023-12-15 15:00:00 +08:00
    @lsk569937453 我使用的就是 go build 的二进制包启动的
    pkoukk
        19
    pkoukk  
       2023-12-15 18:03:48 +08:00
    简单啊,你测试下换几个端口,如果还有问题就是你代码写的问题
    如果没问题就是你环境的问题
    mangoDB
        20
    mangoDB  
       2023-12-15 18:27:24 +08:00
    netstat -n | grep TIME_WAIT
    julyclyde
        21
    julyclyde  
       2023-12-15 18:35:55 +08:00
    @zhoulq7 iptables 转发的情况并不会发生冲突
    只是很单纯的无法生效而已
    julyclyde
        22
    julyclyde  
       2023-12-15 18:37:23 +08:00
    if err != nil {
    logger.Log.Fatal(fmt.Sprintf("err=%v", err))
    请你在这里运行一下 netstat -anp
    这里应该是能抓到事故现场的
    }
    pennai
        23
    pennai  
       2023-12-16 08:57:24 +08:00
    你换个端口号,如果换了端口号还是同样的报错,看看是不是你写的代码有问题,这个函数跑了多次
    lifei6671
        24
    lifei6671  
       2023-12-17 11:48:32 +08:00
    你可以尝试,只启动端口,不建立客户端连接,这种情况下是不是就不存在端口被占用的情况了。
    如果是的话,那么可能是因为服务器端主动断开连接后,这个服务器监听的端口需要等待 2MSL 周期才能再使用。
    这个时间会很短,估计在你执行 netstat 命令的时候端口已经释放了。
    可以尝试缩短 TIME_WAIT 的时间,或者在关闭服务器之前,将所有客户端都 close 了再关闭服务端。
    c00WKmdje2wZLrSI
        25
    c00WKmdje2wZLrSI  
    OP
       2023-12-18 01:29:13 +08:00
    @julyclyde 感谢,抓到事故现场了,的确有进程监听了那个端口
    c00WKmdje2wZLrSI
        26
    c00WKmdje2wZLrSI  
    OP
       2023-12-18 02:19:31 +08:00
    @julyclyde 说错了,是有进程使用那个端口进行非监听状态的连接,导致我使用 netstat -tuln 找不到进程,而使用 netstat -anp 找到了
    julyclyde
        27
    julyclyde  
       2023-12-18 10:20:19 +08:00
    @c00WKmdje2wZLrSI 你之前没有加-a 吧
    -a 就是搜 LISTEN 的

    没明白你说的“非监听状态”是啥意思啊
    c00WKmdje2wZLrSI
        28
    c00WKmdje2wZLrSI  
    OP
       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
        29
    julyclyde  
       2023-12-18 10:27:52 +08:00
    @c00WKmdje2wZLrSI GPT 说的和 manpage 也没啥区别啊

    那你抓到的现场,它是 ESTABLISHED 还是 LISTEN 呢?
    c00WKmdje2wZLrSI
        30
    c00WKmdje2wZLrSI  
    OP
       2023-12-18 10:28:19 +08:00
    @julyclyde ESTABLISHED
    julyclyde
        31
    julyclyde  
       2023-12-18 10:29:26 +08:00
    @c00WKmdje2wZLrSI 那我觉得 GPT 肯定不会告诉你 ip_local_port_range 这个词
    c00WKmdje2wZLrSI
        32
    c00WKmdje2wZLrSI  
    OP
       2023-12-18 11:05:19 +08:00
    @julyclyde 是的,不会,而且我发现是另外一个进程和 mysql 通信时临时占用了端口,并且还是随机占用端口,一段时间后又释放了端口,不知道该怎么设置来避免
    julyclyde
        33
    julyclyde  
       2023-12-18 20:34:17 +08:00
    @c00WKmdje2wZLrSI 那你就搜搜这个词
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2675 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 14:37 PVG 22:37 LAX 07:37 JFK 10:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86