panjf2000 / gnet

🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go.
https://gnet.host
Apache License 2.0
9.55k stars 1.03k forks source link

[Question]: 请教运行在serverless中http的Keep-Alive应该如何配置 #514

Closed joyanhui closed 11 months ago

joyanhui commented 11 months ago

Actions I've taken before I'm here

Questions with details

阿里云的servless 执行httpserver 要求 配置Keep-Alive ,相关代码如下

main

// 启动 tcp with http_get
    var multicore bool
    flag.IntVar(&port, "port", port, "--port "+ServPort)
    flag.BoolVar(&multicore, "multicore", false, "--multicore true")
    flag.Parse()
    echo := &echoServer{addr: fmt.Sprintf("tcp://:%d", port), multicore: multicore}
    log.Fatal(gnet.Run(echo, echo.addr, gnet.WithMulticore(multicore), gnet.WithReusePort(true)))

OnTraffic

func (es *echoServer) OnTraffic(c gnet.Conn) gnet.Action {
    var is_notAllow bool = false // 
    var replyMsg []byte          //回复给客户端的消息
    var tcpRawMsgArr []string    //客户端消息拆分
    var cid string               //客户端cid
    var clientIP string = ""     //客户端ip

    buf, _ := c.Next(-1)
    if int64(len(buf)) > MaxMsgSize { //请求太长
        c.Write([]byte("too long  over maxsize"))
        //return gnet.Close
        return gnet.None
    }
    tcpRawMsg := strings.TrimSpace(string(buf)) 
    is_http := strings.HasPrefix(tcpRawMsg, "GET") //简单判断是否是 http get请求 
//省略一部分 逻辑代码....
    if !is_notAllow {
        // .... 省略的代码
    }
    if is_notAllow { //防止空白消息
        if len(replyMsg) == 0 {
            replyMsg = []byte("err|unknown") 
        }
    } else {
        replyMsg = []byte("ok|pong") //回复消息
    }
    //============   返回消息  =========== start
    if is_http {
        //长度计算
        //joinLengthBytes := bytes.Join([][]byte{[]byte(strconv.Itoa(len(replyMsg))), []byte("\r\n\r\n")}, nil)
        joinLengthBytes := []byte(strings.Join([]string{strconv.Itoa(len(replyMsg)), "\r\n\r\n"}, ""))
        htmlList := [][]byte{
            //[]byte("HTTP/1.1 200\r\nServer:gnet\r\nContent-Type:text/plain\r\nContent-Length:"),
            []byte("HTTP/1.1 200\r\nServer:gnet\r\nConnection: Keep-Alive\r\nKeep-Alive: timeout=86400\r\nContent-Type:text/plain\r\nContent-Length:"),
            joinLengthBytes,
            replyMsg,
        }
        http_response := bytes.Join(htmlList, nil)
        c.Write(http_response)
    } else {
        c.Write(replyMsg)
    }
    //============   返回消息  =========== end
    //return gnet.Close
    return gnet.None
}

severless相关说明: https://help.aliyun.com/zh/fc/user-guide/principles?spm=a2c4g.11186623.0.i4#section-ffl-tm3-txg 我这里一直报错

{"errorMessage":"Process exited unexpectedly before completing request (duration: 4588ms, maxMemoryUsage: 4.73MB)"}%                        

Code snippets (optional)

No response

panjf2000 commented 11 months ago

不太懂你这个问题,你要设置 keepalive 直接设置这个就行了,现在是 gnet server 总是启动后退出吗?

joyanhui commented 11 months ago

不太懂你这个问题,你要设置 keepalive 直接设置这个就行了,现在是 gnet server 总是启动后退出吗?

感谢大佬回复,我经过检查后发现,可能是因我的一个Ticker在清理超时的空tcp连接导致的,在servless好像不能这样搞。我暂时去掉了这部分代码还在排查可能存在的其他问题。