Go net/http Client 某些参数并不是并发安全的?

新手上路,请多包涵

在官方文档中有提到 net/http 是协程安全的,应该复用。

The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.

但使用 Client 发起请求时,有一部分请求的设置是以函数或字段的方式放在 Client 的参数中的。例如 Proxy 代理、重定向检查、超时设置。要设置的话必须像以下这般设置:

func RedirectFunc(req *http.Request, via []*http.Request) error {
        if len(via) > 5 {
            err := &RedirectError{r}
            return WrapErr(err, "RedirectError")
        }
        return nil
}

client.CheckRedirect = RedirectFunc  // 设置重定向

这样的话就会造成一个问题,在并发的过程中如果要更改重定向次数的话,就会有并发安全问题,设置 Proxy 代理和超时时间也有这个问题。

比如在这样一个假设情况中,我现在有 10000 个请求需要并发,每个请求需要设置不同的特定 Proxy 代理。那么这时候使用全局的 Client,在每个协程中更改 client.CheckRedirect 函数,然后发起请求,显然会有并发问题,发起请求时使用的并不一定是指定的那个 Proxy。

想了想解决的办法:

  1. 每个请求新建一个 Client?
  2. 把更改参数和请求一起加锁锁起来?

请问这种情况有靠谱的解决方法吗?

阅读 5.3k
3 个回答
✓ 已被采纳新手上路,请多包涵

创建多个Client,使用相同参数的请求用同一个Client,提前设置好参数。

重用 Client 的主要目的是重用/缓存 TCP 连接(cached TCP connections),但对于你的需求

有 10000 个请求需要并发,每个请求需要设置不同的特定 Proxy 代理

来说,缓存 TCP 连接没用,因此不重用 Client 也无妨。

至于共享 Cookie,你只需要共享 Client.CookieJAR 便可。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏