猿问

拨号TCP报错:高并发请求一段时间后超时或i/o超时

我最近在通过以下方式开发高并发 http 客户端时遇到了一个问题valyala/fasthttp:客户端在前 15K~ 请求中工作正常,但之后越来越多dial tcp4 127.0.0.1:80: i/o timeout并dialing to the given TCP address timed out发生错误。


示例代码

var Finished = 0

var Failed = 0

var Success = 0


func main() {

    for i := 0; i < 1000; i++ {

        go get()

    }

    start := time.Now().Unix()

    for {

        fmt.Printf("Rate: %.2f/s Success: %d, Failed: %d\n", float64(Success)/float64(time.Now().Unix()-start), Success, Failed)

        time.Sleep(100 * time.Millisecond)

    }

}


func get() {

    ticker := time.NewTicker(time.Duration(100+rand.Intn(2900)) * time.Millisecond)

    defer ticker.Stop()

    client := &fasthttp.Client{

        MaxConnsPerHost: 10000,

    }

    for {

        req := &fasthttp.Request{}

        req.SetRequestURI("http://127.0.0.1:80/require?number=10")

        req.Header.SetMethod(fasthttp.MethodGet)

        req.Header.SetConnectionClose()

        res := &fasthttp.Response{}

        err := client.DoTimeout(req, res, 5*time.Second)

        if err != nil {

            fmt.Println(err.Error())

            Failed++

        } else {

            Success++

        }

        Finished++

        client.CloseIdleConnections()

        <-ticker.C

    }

}

细节

服务器建立在labstack/echo/v4客户端出现超时错误时,服务器没有任何错误,通过Postman或类似浏览器的方式手动执行请求Chrome都可以正常工作。


客户端在第一个 15K~ 请求中运行良好,但之后,出现越来越多的超时错误并且输出越来越少Rate。我搜索了google和github,发现这个问题可能是最合适的,但没有找到解决方案。


另一个小问题...

正如您所看到的,当客户端启动时,它首先会产生一些the server closed connection before returning the first response byte. Make sure the server returns 'Connection: close' response header before closing the connection错误,然后正常工作直到大约 15K 问题,然后开始产生越来越多的超时错误。为什么它会在开始时产生 Connection closed 错误?


机器信息

配备 16GB Ram 并运行 macOS Monterey 12.4 的 Macbook Pro 14 2021 (Apple M1 Pro)


慕运维8079593
浏览 1010回答 1
1回答

呼啦一阵风

所以基本上,如果你试图打开一个连接然后尽快关闭它,它不会像“连接#1 使用一个端口然后立即返回它”,需要做很多处理,所以如果你想同时发送很多请求,我认为最好尽可能地重用连接。例如,在fasthttp:req := fasthttp.AcquireRequest()res := fasthttp.AcquireResponse()defer fasthttp.ReleaseRequest(req)defer fasthttp.ReleaseResponse(res)// Then do the request below
随时随地看视频慕课网APP

相关分类

Go
我要回答