谁知道这个错误是什么原因导致的吗?急!

DreamingPHPer · 2023-09-05 17:05:14 · 1771 次点击 · 预计阅读时间不到 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2023-09-05 17:05:14 的文章,其中的信息可能已经有所发展或是发生改变。

使用http.NewRequest并发请求同一个接口(参数不一样)时,一段时间后,会提示下面这个错误:谁知道是什么原因吗 connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1771 次点击  
加入收藏 微博
4 回复  |  直到 2023-09-06 16:01:42
jjmgx
jjmgx · #1 · 2年之前

端口被用完了,你请求后body没有close吧。

DreamingPHPer
DreamingPHPer · #2 · 2年之前

已经添加close了

func Get(api string, params, headers map[string]string, timeout int) (error, int, interface{}) {
    // 创建 http 客户端
    defaultTransport := http.DefaultTransport
    tr := *defaultTransport.(*http.Transport)
    tr.TLSClientConfig = &tls.Config{
        InsecureSkipVerify: true,
    }
    tr.DisableKeepAlives = true
    client := &http.Client{Transport: &tr}

    // 设置超时时间
    if timeout > 0 {
        client.Timeout = time.Duration(timeout) * time.Second
    } else {
        client.Timeout = time.Duration(5) * time.Second
    }

    // 创建请求
    req, _ := http.NewRequest("GET", api, nil)

    // GET 请求携带查询参数
    q := req.URL.Query()
    if len(params) > 0 {
        for key, value := range params {
            q.Add(key, value)
        }
    }
    req.URL.RawQuery = q.Encode()

    // 设置请求头
    if len(headers) > 0 {
        for key, value := range headers {
            req.Header.Set(key, value)
        }
    }

    // 发送请求
    req.Header.Set("Connection", "close")
    resp, err := client.Do(req)
    if err != nil {
        if strings.Contains(err.Error(), "Timeout") {
            return Get(api, params, headers, timeout)
        }

        // 上报日志
        return err, 0, nil
    }

    // 关闭连接
    defer resp.Body.Close()

    // 读取内容
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        // 上报日志
        return err, resp.StatusCode, nil
    }

    return nil, resp.StatusCode, string(body)
}
jjmgx
jjmgx · #3 · 2年之前

client := &http.Client{Transport: &tr} 应该在调用子程序前创建一个client,这样会被复用,你的是每次子程序创建一个,关闭后就占用了,要到一定时间才会释放,所以时间长了,线程多了,端口不够用了。把client在全局创建好,每次传入才对,而且创建时可以指定最大的连接数,这样可以控制使用的链接不会太多。

DreamingPHPer
DreamingPHPer · #4 · 2年之前
jjmgxjjmgx #3 回复

client := &http.Client{Transport: &tr} 应该在调用子程序前创建一个client,这样会被复用,你的是每次子程序创建一个,关闭后就占用了,要到一定时间才会释放,所以时间长了,线程多了,端口不够用了。把client在全局创建好,每次传入才对,而且创建时可以指定最大的连接数,这样可以控制使用的链接不会太多。

嗯嗯,可以了,谢谢啦

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传