首页 技术 正文
技术 2022年11月21日
0 收藏 386 点赞 2,269 浏览 2024 个字

http是我们最常见的客户端/服务端传输协议,在golang中,默认的net/http包有一些坑位,需要调整以获得更加性能。

在golang程序中,我也遇到因为不合理使用 http client导致的程序崩溃问题。

坑:1:默认的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。

这里有个有关HttpClient Timeout的排障问题,你可参考。


.NET HttpClient Timeout: The default value is 100,000 milliseconds (100 seconds).

坑2:默认的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配置,但是.NET Core这个PerServer被设置为int.maxvalue,所以我们无需关注,.NET真香。

我的收获

通过本文,我们谈到了golang HttpClient的2个坑位、由坑位导致的现象和排障思路,各位看官,有则改之无则加勉。

并且我们对比了.NET Core语言中HttpClient的默认配置,各位看官心中有数。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,023
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,513
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,361
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,143
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,774
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,853