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的默认配置,各位看官心中有数。

Gopher必读:HttpClient的两个坑位的更多相关文章

  1. 【干货】基于镜像部署的Gitlab-CI/CD实践和坑位指南

    引言 看过前文的博友可能注意到我是把 部署dll文件拷贝到生产机器,之后在生产机器上使用docker-compose即时创建镜像, 并没有完成CI/CD, 只是在原来传统部署方式下 将部署文件容器化. ...

  2. 两个坑-Linux下Network-Manager有线未托管-DNS resolv.conf文件开机被清空

    Linux里面有两套管理网络连接的方案: 1./etc/network/interfaces(/etc/init.d/networking) 2.Network-Manager 两套方案是冲突的,不能 ...

  3. iscroll遇到的两个坑

    最近移动端闪付遇到的两个坑做下总结: 1.使用iscroll后,滑动并没有生效 解决方案: 首先要查看:结构是否正确: <div id="wrapper">   //w ...

  4. 记自己在spring中使用redis遇到的两个坑

    本人在spring中使用redis作为缓存时,遇到两个坑,现在记录如下,算是作为自己的备忘吧,文笔不好,望大家见谅: 一.配置文件 <!-- 加载Properties文件 --> < ...

  5. [PHP] 算法-两个n位的二进制整数相加问题PHP实现

    两个n位二进制数分别存储在两个n元数组A和B中,这两个整数的和存在一个n+1元的数组C中答:此问题主要是考察相加进位的问题,元素1+1 =0 并且往前进一位ADD-BINARY(A,B) C=new ...

  6. MySql 5.7安装(随机密码,修改默认密码)两个坑

    MySql 5.7安装(随机密码,修改默认密 下载了MySql 最新版本,安装的过程中,发现了很多新特性 1.data目录不见了 在进行my-default.ini配置的时候 (需要配置 # base ...

  7. .net core HttpClient 使用之掉坑解析(一)

    一.前言 在我们开发当中经常需要向特定URL地址发送Http请求操作,在.net core 中对httpClient使用不当会造成灾难性的问题,这篇文章主要来分享.net core中通过IHttpCl ...

  8. jQueryUI Draggable 和 Droppable 配合使用时遇到的两个坑

    jQueryUI 的 拖拽插件极大的方便了开发者对拖拽功能的实现,但是官方教程给的太笼统,在具体实现的时候很多地方不明确,这里说一下我遇到的两个 "小坑": 1:Draggable ...

  9. redis主从遇到的两个坑

    最近在使用redis主从的时候做了下面两件事情: 1 希望redis主从从操作上分析,所有写操作都在master上写,所有读操作都在从上读. 2 由于redis的从是放在本地的,所以有的key的读写操 ...

随机推荐

  1. 【刷题-LeetCode】121 Best Time to Buy and Sell Stock

    Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...

  2. 华为联运游戏审核驳回:在未安装或需更新HMS Core的手机上,提示安装,点击取消后,游戏卡屏(集成的6.1.0.301版本游戏SDK)

    问题描述 更新游戏SDK到6.1.0.301版本之后,游戏包被审核驳回:在未安装或需更新华为移动服务版本(HMS Core)的手机上,提示安装华为移动服务(HMS Core),点击取消,游戏卡屏.修改 ...

  3. WebGPU相关的资源学习和社区

    我在网上搜寻了很多关于WebGPU相关的资料: #我觉得首先在B站上看到的徐博士免费教程非常好,讲解详细,并且评论回复比较快,都会有回应,徐博士B站网址:https://space.bilibili. ...

  4. Go 面向对象三大特性

    #### Go 中面向对象的三大特性上周因为有一些事情,停更了; 停更的这段时间,花了点时间做了一个小项目(https://github.com/yioMe/node_wx_alipay_person ...

  5. IoC容器-Bean管理XML方式(注入内部bean和级联赋值)

    注入属性-内部bean和级联赋值 (1)一对多关系:部分和员工 一个部门有多个员工,一个员工属于一个部门 部门是一,员工是多 (2)在实体类之间表示一对多关系 (3)在spring配置文件中进行配置 ...

  6. 【重构前端知识体系之HTML】HTML5给网页音频带来的变化

    [重构前端知识体系之HTML]HTML5给网页音频带来的变化 引言 音乐播放,相信大家都很熟悉,但是早在之前的音乐播放之前,你的浏览器会问你,是否下载flash插件.然而现在,估计一些年轻的开发者都不 ...

  7. 【建议收藏】Redis超详细入门教程大杂烩

    写在前边 Redis入门的整合篇.本篇也算是把2021年redis留下来的坑填上去,重新整合了一翻,点击这里,回顾我的2020与2021~一名大二后台练习生 NoSQL NoSQL(NoSQL = N ...

  8. TensorFlow 深度学习中文第二版·翻译完成

    原文:Deep Learning with TensorFlow Second Edition 协议:CC BY-NC-SA 4.0 不要担心自己的形象,只关心如何实现目标.--<原则>, ...

  9. AT2400 [ARC072B] Alice&Brown

    通过打表后可以发现,当初始石头数 \(|X - Y| \le 1\) 时先手必败否则先手必胜. 我们考虑使用归纳证明这个结论,显然 \((1, 0), (1, 1)\) 时是成立的. 基于观察,我们可 ...

  10. shiro-springboot整合,平行依赖

    最近在弄shiro,把shiro单独提出来,弄成一个子项目,这样可以降低项目的冗余,但是把shiro打成jar包后,另一个项目添加其依赖后,在IDE项目中正常的运行,打成jar包后运行,则不断的报错 ...