gpt4 book ai didi

go - Websocket 打开的文件太多

转载 作者:行者123 更新时间:2023-12-01 19:53:01 26 4
gpt4 key购买 nike

进程留下太多打开的文件描述符。当我这样做时:lsof -p $pid,大部分结果是(大约 80%):

points2 28360 root 911u sock 0,9 0t0 42082509 protocol: TCPv6

在 FD Type 变为 'sock' 之前,它会保持 CLOSE_WAIT 一段时间。我注意到其中一些“sock”FD 消失了,一些永远存在

打开文件数量逐渐增加,波动很小,直到没有达到最大值 1024。目前我将允许的最大打开文件数量设置为 4096,以使进程工作时间更长。

srvTLS := &http.Server{
Addr: utils.PortSocketTLS,
ReadTimeout: 10 * time.Second,
WriteTimeout: 15 * time.Second,
}
srvTLS.SetKeepAlivesEnabled(false)

处理程序:

func WsRoom(w http.ResponseWriter, r *http.Request) {
ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
return
}
...other stuff
}

作者conn

func PlayerWriter(pc *model.PlayerConn) {
ticker := time.NewTicker(utils.PingPeriod)
defer func() {
ticker.Stop()
pc.WS.Close()
}()
for {
select {
case message, ok := <-pc.Ch:
pc.WS.SetWriteDeadline(time.Now().Add(utils.WriteWait))
if !ok {
pc.WS.WriteMessage(websocket.CloseMessage, []byte{})
return
}

err := pc.WS.WriteMessage(websocket.TextMessage, message)
if err != nil {
return
}
inst := &model.PlayerLeftInstruction{}
_ = json.Unmarshal(message, inst)

if inst.Instruction == utils.UtilAFK || inst.Instruction == utils.RoomMoneyLess {
return
}
break
case <-ticker.C:
pc.WS.SetWriteDeadline(time.Now().Add(utils.WriteWait))
if err := pc.WS.WriteMessage(websocket.PingMessage, nil); err != nil {
return
}
break
}
}}

Conn 监听器:

func PlayerListener(pc *model.PlayerConn) {
defer func() {
if r := recover(); r != nil {
}
close(pc.Ch)
pc.Room.Leave <- pc
pc.WS.Close()
}()

pc.WS.SetReadLimit(utils.MaxMessageSize)
pc.WS.SetReadDeadline(time.Now().Add(utils.PongWait))
pc.WS.SetPongHandler(func(string) error { pc.WS.SetReadDeadline(time.Now().Add(utils.PongWait)); return nil })

for {
_, command, err := pc.WS.ReadMessage()
if err != nil {
break
}
si := model.StatusInstruction{}
json.Unmarshal(command, &si)
z := make([]byte, len(command))
copy(z, command)
switch si.Status {
case utils.PlayerLeft:
goto Exit
case utils.MoveTurn, utils.LocalTurn, utils.LocalBetFold, utils.LocalBet, utils.MoveTurnBet:
pc.Room.RoomData.GameBridger.InstCh <- z
break
...some stuff
default:
log.Printf("Unexpected command is responsed it is: %s", string(command))
goto Exit
}
}
Exit:
}

如果需要,我可以分享更多代码。我认为超时问题和与此相关的问题,但我不完全知道我错过了什么

最佳答案

在 lsof 中,TYPE 'sock' 通常表示:没有收到任何东西的套接字连接。由于在某些情况下未关闭已建立的 websocket 连接,我的代码出现了逻辑错误。我也有 goroutine 泄漏(但是它没有影响 lsof 数),pprof 帮助检测泄漏。

关于go - Websocket 打开的文件太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62469640/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com