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. [开发笔记usbTOcan]软件需求分析和软件架构设计

    前面文章进行了系统分析和系统架构设计,手工焊接了一个板子,集合EK-TMC123GXL开发板(请忽略焊接技术) SWE.1 | 软件需求分析 软件需求分析过程的目的是将系统需求的软件相关部分转化为一组 ...

  2. 记录未解决的问题:docker中无法启动mysqld

    首先在docker中安装mysql server的包: sudo yum install mysql sudo yum install mariadb-server mariadb /usr/libe ...

  3. 34.AVL树

    1.创建Node结点 class Node { int value; Node left; Node right; public Node(int value) { this.value = valu ...

  4. 3D建模服务提供更高效、专业的能力,“筑”力开发者

    3D建模服务(3D Modeling Kit)是HMS Core在图形图像领域又一技术开放.3D建模产品的定位就是要做快速.简洁.低成本的3D制作能力,并陆续开放给有3D模型.动画游戏制作等能力诉求的 ...

  5. python33day

    内容回顾 概念 同步异步阻塞和非阻塞 同步阻塞:调用一个函数需要等待这个函数的执行结果,并且在执行这个函数的过程中CPU不工作 inp=input('>>>') 同步非阻塞:调用一个 ...

  6. plsql 视图中 为什么使用替代触发器

    /* 什么是视图? 视图:数据库对象,存的是一个查询命令:当作一个虚拟的数据表来使用: 应用场景: 简化查询操作:不能直接在视图上进行create,insert,update操作: 创建视图? 需要管 ...

  7. 天翼网关免密改桥接&恢复出厂(含修改超密工具)

    路由/桥接模式切换 说明:默认天翼网关用的局域网ip是192.168.1.1,如果不是,则修改为局域网ip. 本机已经是桥接模式,在这里可以输入宽带账号密码转换成路由模式,两个模式之间可以互转. 恢复 ...

  8. RSA公钥加密-私钥解密/私钥加密-公钥解密

    package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import org.apache.log4j.Log ...

  9. Redis 分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!(转)

    基于Redis使用分布式锁在当今已经不是什么新鲜事了. 本篇文章主要是基于我们实际项目中因为redis分布式锁造成的事故分析及解决方案.我们项目中的抢购订单采用的是分布式锁来解决的,有一次,运营做了一 ...

  10. ubuntu php连接oracle数据库

    转载请注明来源:https://www.cnblogs.com/hookjc/ 需要将数据库从mysql迁移到oracle.下了个oracle xe在ubuntu下折腾了好久,都只能启动1521的侦听 ...