golang httpClent,解决EOF问题

“End of File” 意味着客户端和服务器之间的连接在未按预期的情况下被中断了,导致在接收响应时没能拿到完整的数据流

出在几个方面:

  • 连接池管理不当

  • HTTP Keep-Alive机制

  • 服务器主动关闭连接

其中,“时不时EOF”往往和连接池的使用及Keep-Alive机制有关。Golang的http.Client在默认情况下会保持连接,重用之前的TCP连接来提高性能,这就是所谓的Keep-Alive机制

原写法如下:

package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {
  client := &http.Client{}
  req, err := http.NewRequest("GET", "https://example.com", nil)
  if err != nil {
    fmt.Println("Request creation failed:", err)
    return
  }

  resp, err := client.Do(req)
  if err != nil {
    fmt.Println("Request failed:", err)
    return
  }
  defer resp.Body.Close()

  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    fmt.Println("Reading response failed:", err)
    return
  }

  fmt.Println("Response:", string(body))
}

面这个例子是不是看起来很“正经”?但它有个问题,容易触发EOF错误。具体表现就是:在某些场景下(比如请求频繁、服务端连接超时),运行几次就能碰到。

解决方案一:设置超时和重试

  // 增加了超时设置,避免死等   client := &http.Client{    Timeout: 10 * time.Second,  }

 解决方案二:设置Transport,自定义连接池策略

  // 自定义Transport配置  定制连接池策略 调整超时时间,规范Keep-Alive的策略  transport := &http.Transport{    DialContext: (&net.Dialer{      Timeout:   30 * time.Second,  // 连接超时      KeepAlive: 30 * time.Second,  // 保持连接时长    }).DialContext,    MaxIdleConns:          100,   // 最大空闲连接数    IdleConnTimeout:       90 * time.Second,  // 空闲连接超时    TLSHandshakeTimeout:   10 * time.Second,  // TLS握手超时    ExpectContinueTimeout: 1 * time.Second,   // 100-Continue状态超时  }
  client := &http.Client{    Transport: transport,  }

解决方案三:使用第三方库(比如resty)

用resty来做请求,代码更简洁,且内部对连接池管理、重试机制等都有优化。如果要做HTTP请求的“高频选手”,那可以考虑切换到这个库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值