golang的http几个重要参数

场景一: 单机客户端需要并发10万http请求到一个同一个服务器

  1. 客户端并发发动http请求,根据tcp协议,谁主动关闭谁就进入TIME_WAIT(等个1-4分钟),且一般都是客户端主动断开, 如此发送请求的客户端端口很定会不够用的(哪怕你调到系统最大级别)

TIME_WAIT: 锁定的是 协议、本地IP、本地端口、远程IP、远程端口 这样一组资源(禁止规定时间内本机再使用这样一组资源)。需要等个2 MSL

方案:

  • 第一步: http.Client 初始化一个自定义的全局客户端对象(避免影响全局的)

  • 第二步:设置client的 MaxConnsPerHost 。它代表同一个host+port最多新建的tcp个数,0(默认)表示无限制。这个参数你要是不设置,你有多少端口都给你用完了。设置了达到最大值后就会阻塞。

  • 第三步:设置client的 MaxIdleConnsPerHost 参数(默认为2),搞大一点比如1000,该参数是依据 host+port 去缓存tcp连接句柄的个数配置。有缓存的tcp句柄就不必每个请求都从零去发动http请求, 现成的用起来就不必担心端口资源了,go里面被称之为 http电池。 同时它也代表host+port 下最多的闲着的tcp连接。 超过 MaxIdleConnsPerHost 又小于 MaxConnsPerHost 就会触发客户端不停的主动关闭tcp链接,

  • 第四步: 设置client的 IdleConnTimeout (默认 90 * time.Second),第三步下的闲tcp一直无流量就一直被闲着,给个最大无流量使用的时间限制,超时就回收掉(一直无人用留它干嘛)
    *第五步: 设置client的 MaxIdleConns (默认100),不区分host单个client下最多打开的tcp连接数

总结:其实第4,5步系统默认有值,拿出来是需要注意不要跟1,2,3配置冲突了

//golang默认的http.Client的 Transport 配置
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,
}

场景二:单机客户端需要并发10万http请求到10万个不同服务器

第一步:将进程配置到操作系统允许的最大端口个数(6万多)
第二步:考虑将time_wait的系统时间调小(但这个感觉还是遵循tcp默认规则好些)
第三步:考虑自己设计一个资源池安全限速(令牌桶或者漏桶算法)
第四步:参考场景一

参考文献

https://zhuanlan.zhihu.com/p/361792917?utm_medium=social&utm_oi=1351439228794986497

你可能感兴趣的:(golang的http几个重要参数)