如何解决多线程如何影响http保持连接?
var (
httpClient *http.Client
)
const (
MaxIdleConnections int = 20
RequestTimeout int = 5
)
// init HTTPClient
func init() {
client := &http.Client{
Transport: &http.Transport{
MaxIdleConnsPerHost: MaxIdleConnections,},Timeout: time.Duration(RequestTimeout) * time.Second,}
return client
}
func makeRequest() {
var endPoint string = "https://localhost:8080/doSomething"
req,err := http.NewRequest("GET",....)
response,err := httpClient.Do(req)
if err != nil && response == nil {
log.Fatalf("Error sending request to API endpoint. %+v",err)
} else {
// Close the connection to reuse it
defer response.Body.Close()
body,err := IoUtil.ReadAll(response.Body)
if err != nil {
log.Fatalf("Couldn't parse response body. %+v",err)
}
log.Println("Response Body:",string(body))
}
}
我在Go中有以下代码。 Go使用http-keep-alive连接。因此,据我了解,httpClient.Do(req)
不会创建新的连接,因为golang使用默认的持久连接。
-
以我的理解,HTTP持久连接一次发出一个请求,即第二个请求只能在第一个响应之后发出。但是,如果多个线程调用
makeRequest()
会发生什么?httpClient.Do(req)
会在上一个请求得到响应之前发送另一个请求吗? -
我假定服务器使客户端建立的任何保持活动连接超时。如果服务器超时,那么下次调用
httpClient.Do(req)
时,它将建立一个新的连接吗?
解决方法
http.Client
有一个Transport
,它向其委派了发出请求的许多底层细节。通过为客户提供自定义传输,您几乎可以更改任何内容。该答案的其余部分将主要假设您正在使用http.DefaultClient
或至少一个具有http.DefaultTransport
的客户端。
发出新请求时,如果与相应服务器的空闲连接可用,则传输将使用它。
如果没有空闲连接可用(因为从来没有空闲连接,或者因为其他goroutine都使用了它们,或者因为服务器关闭了连接,或者存在其他错误),那么传输将考虑建立新的连接,受MaxConnsPerHost
限制(默认值:无限制)。如果将超过MaxConnsPerHost
,则该请求将被阻塞,直到现有请求完成并且连接可用为止。否则,将为此请求建立新的连接。
请求完成后,客户端将缓存连接以供以后使用(受MaxIdleConns
和MaxIdleConnsPerHost
的限制; DefaultTransport
的全局限制为100个空闲连接,没有限制每个主机)。
如果闲置连接不用于发出请求,则它们将在IdleConnTimeout
之后关闭; DefaultTransport
的限制为90秒。
所有这些都意味着默认情况下,Go将建立足够的连接以满足并行性(不超过您可以调整的某些限制),但它还将通过维护一个空闲连接池来尽可能多地重用保持活动连接一段时间。
,这不会影响http保持活动连接,根据您的代码,您正在使用全局httpClient,如果按预期在多个线程中调用,则不会创建新连接,它还会读取response.Body
在关闭之前。如果提供的response.Body
是io.Closer
,它将在请求后关闭。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。