默认的HttpClient
默认的HttpClient不包含请求超时时间,如果你使用http.Get(url)或者&Client{}, 这将会使用http.DefaultClient,这个结构体内no timeout
。
假如发出请求的服务端API有问题:没有及时响应httpclient请求但是保持了连接, 在高并发情况下,打开的连接数会持续增长,最终导致客户端服务器资源到达瓶颈。
解决方案:不要使用默认的HTTPClient, 总是为HttpClient指定Timeout
client := &http.Client{ Timeout: 10 * time.Second, }
HttpClient Timeout包括连接、重定向(如果有)、从Response Body读取的时间,内置定时器会在Get,Head、Post、Do 方法之后继续运行,直到读取完Response.Body。
.NET HttpClient Timeout
: The default value is 100,000 milliseconds (100 seconds).
02
默认的Http Transport
目前常见的HttpClient(.NET Core,golang) 都会有连接池的概念, 客户端会尽量复用池中已经建立的连接。
go的Transport
可理解为连接池中的连接。
// DefaultTransport is the default implementation of Transport and is // used by DefaultClient. It establishes network connections as needed // and caches them for reuse by subsequent calls. It uses HTTP proxies // as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and // $no_proxy) environment variables. var DefaultTransport RoundTripper = &Transport{ Proxy: ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, ForceAttemptHTTP2: true, MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } // DefaultMaxIdleConnsPerHost is the default value of Transport's // MaxIdleConnsPerHost. const DefaultMaxIdleConnsPerHost = 2
默认的
•golang的Http Client连接池有100个连接
•每个连接默认的空闲时间90s(90s内有请求过来,可以复用该连接)
•上面的KeepAlive是tcp探活的时间间隔,并不是我们HTTP连接复用的 Keep-Alive
有坑位的是DefaultMaxIdleConnsPerHost=2
:每个主机(服务)保留的空闲连接数是2个。
这意味着,当首次针对某主机发出100个请求,这100个请求会同时利用连接池中的100个连接,之后因为这个限制,客户端被迫主动关闭98个连接,此时客户端机器会出现98 个time_wait
(time_Wait会存在2MSL,大概2min,占用了机器资源),
新的请求被迫新开连接,然后立马主动关闭,只维持2个复用连接, 累积到最后造成客户端机器存在大量time_Wait
的连接。
从我司实际项目看,造成CPU高涨,并且无法新开连接。
解决方案:不要使用默认Transport,增加MaxIdleConnsPerHost
本人回顾了.NET HttpClient,貌似不用刻意关注这个值。
实际上,.NET也存在这个MaxIdleConnectionPerServer配置👈
[1],但是.NET Core这个PerServer被设置为int.maxvalue,所以我们无需关注,.NET真香。
03
我的收获
通过本文,我们谈到了golang HttpClient的2个坑位、由坑位导致的现象和排障思路,各位看官,有则改之无则加勉。
并且我们对比了.NET Core语言中HttpClient的默认配置,各位看官,家里有粮心中不慌。