为什么使用 golang http包 会把 linux 句柄打满?

news2025/1/21 10:12:57

最近工作的时候一个接入服务需要测性能测试,万万没想到测出了一个把 linux 句柄打满的问题

具体是什么问题呢,我们一起来看看

正常操作

项目中,有一些 http 请求是这样写的:

  • 请求 https 的地址,为了绕过 tls ,加上了 TLSClientConfig: &tls.Config{InsecureSkipVerify: true} 配置
  • 正常访问我们需要的请求的地址
  • 正常获取我们的期望的数据,正常解析
func main() {
	client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}
	resp, err := client.Get("https://www.xxxxxx.com")
	if err != nil {
		fmt.Println("Get err : ", err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}

例如如下是访问百度的结果,没有什么毛病

t# go run main.go
<html>
<head>
        <script>
                location.replace(location.href.replace("https://","http://"));
        </script>
</head>
<body>
        <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>

发现问题

可是例如这样的请求代码拿去做性能测试的话,我们实际遇到的问题是,linux 句柄数被打满了

句柄数被打满了,简单的思考有如下 2 个初步的可能:

  • linux 句柄数设置过小
  • http 代码没有释放连接

我知道的有如下 3 种方式,可以修改 linux 的句柄数:

1、修改 /etc/profile

直接修改 /etc/profile , 在 该文件最后加上如下语句

ulimit -n 65535

这里举个例子,设置 65535 个句柄数

修改后 执行

 source /etc/profile

查看效果

ulimit -a

2、修改 limits.conf 文件

直接修改 limits.conf,让其生效

vim /etc/security/limits.conf

3、修改 login 文件

我们可以在 /etc/pam.d/login 文件中 添加最下面一行

 session   required   pam_limits.so

例如上面这样添加

上述 第2 和 第3 种方式,需要重新 ssh 进入到服务器,或者重启服务器才可生效

虽然我增大了 linux 句柄数,发现在性能测试中,只是测得可以稍微久一点了,可是最终还是连接数被打满,这是为什么呢?

仔细查看了代码,代码中也有关闭 http 的连接

那么问题会是处在哪里呢?

找到问题解决问题

仔细查看了代码,只有一个怀疑点了,那就是下面这句话

client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

最初开始使用这句话的时候,目的也只是为了绕过 tls ,并没有考虑太多,现在仔细看看 http.Transport 结构体里面的功能

type Transport struct {
	idleMu       sync.Mutex
	closeIdle    bool                                // user has requested to close all idle conns
	idleConn     map[connectMethodKey][]*persistConn // most recently used at end
	idleConnWait map[connectMethodKey]wantConnQueue  // waiting getConns
	idleLRU      connLRU

	reqMu       sync.Mutex
	reqCanceler map[cancelKey]func(error)

	altMu    sync.Mutex   // guards changing altProto only
	altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme

	connsPerHostMu   sync.Mutex
	connsPerHost     map[connectMethodKey]int
	connsPerHostWait map[connectMethodKey]wantConnQueue // waiting getConns
    ...........省略多行   ...........
    
    // TLSClientConfig specifies the TLS configuration to use with
	// tls.Client.
	// If nil, the default configuration is used.
	// If non-nil, HTTP/2 support may not be enabled by default.
	TLSClientConfig *tls.Config

	// TLSHandshakeTimeout specifies the maximum amount of time waiting to
	// wait for a TLS handshake. Zero means no timeout.
	TLSHandshakeTimeout time.Duration

	// DisableKeepAlives, if true, disables HTTP keep-alives and
	// will only use the connection to the server for a single
	// HTTP request.
	//
	// This is unrelated to the similarly named TCP keep-alives.
	DisableKeepAlives bool
    ...........省略多行   ...........
    }

仔细查看了上述结构之后,发现 DisableKeepAlives 可以禁用长连接,,每个请求都会创建一个连接,切请求完就会马上关闭连接

正确设置 Transport 后问题得以解决

client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			DisableKeepAlives: true,
		},
	}

该问题表象看上去是没有设置好 http.Transport

实际上是 go http 包对于连接的管理 我们还没有去熟悉他,对于他关于连接的具体实现和细节代码,日后有机会再分享

代码修改完毕,性能测试果然正常通过,对技术对代码一定要有敬畏之心

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文精读】基于流序列的基于残差图卷积网络的匿名网络流量识别

Flow Sequence-Based Anonymity Network Traffic Identification with Residual Graph Convolutional Networks 基于流序列的基于残差图卷积网络的匿名网络流量识别 摘要 从网络流量中识别匿名服务是网络管理和安全的关键任务。 目前&#xff0c;一些基于深度学习的工作已经…

JavaScript 事件案例

文章目录JavaScript 事件案例统计输入字符数量验证输入内容搜索框复选框的全选和反选下拉列表自定义鼠标右键菜单ctrlenter发送消息规定范围内拖拽元素两元素碰撞切换图片内容滚动条鼠标滚动缩放图片JavaScript 事件案例 统计输入字符数量 <!DOCTYPE html> <html>…

一文看懂C/C++编译过程以及g++编译选项

前言在linux系统下&#xff0c;输入man g&#xff0c;即可以看到gcc官方文档对gcc编译选项的详细说明&#xff0c;本文也主要是在官方文档基础上&#xff0c;对gcc/g编译过程和一些编译选项进行了总结和说明&#xff0c;希望对学习这块内容的人有所帮助。1、编译的四个阶段一般…

Cannot read properties of null (reading ‘pickAlgorithm‘)

2568 verbose node v16.15.0 2569 verbose npm v8.5.5 2570 error Cannot read properties of null (reading ‘pickAlgorithm’) 2571 verbose exit 1 2572 timing npm Completed in 20918ms 2573 verbose unfinished npm timer reify 1673607123032 2574 verbose unfinished …

openSUSE-Leap-15.4系统分析和微调指南-略读笔记

openSUSE-Leap-15.4系统分析和微调指南——略读笔记 openSUSE Leap 15.4 System Analysis and Tuning Guide SUSE 产品文档-中文(简体)-下载中心 https://documentation.suse.com/zh-cn/sled/15-SP4/ 单击English选择简体中文——单击PDF是可以下载的&#xff0c;例如System A…

学习记录:featurecounts

Input one or more files of aligned reads (short or long reads) in either SAM or BAM formata list of genomic features in either Gene Transfer Format (GTF) or General Feature Format (GFF) or Simplified Annotation Format (SAF)比对后产生的bam或者sam文件&#…

一次简单的本机调试webshell的经历

环境安装 安装php和nginx&#xff0c;不再赘述 apt-get update apt-get install nginx这里我的版本是php7.4 # php -v PHP 7.4.33 (cli) (built: Jan 6 2023 16:10:36) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend …

Optional最佳实践(对象操作利器)

前篇文章已经总结了集合的操作是如何在Java8优化的&#xff1a;函数编程和Stream_txxs的博客-CSDN博客&#xff0c;这篇文章总结一下对于对象如何利用Java8进行操作&#xff0c;这样对于大部分代码都可以用Java8的语法进行操作了。 一、 Optional 是什么 Optional 的作者 Bri…

收购淘米后,MMV加速走向迪士尼式IP开发之旅

一家纯正的元宇宙控股公司与经典IP公司碰撞&#xff0c;能擦出怎样的火花&#xff1f;这个问题或将在不远的将来得出答案。 1月12日晚间&#xff0c;刚在一周前以SPAC方式登陆纳斯达克的MMV&#xff08;MultiMetaVerse&#xff0c;即“元宇宙控股”&#xff09;&#xff0c;宣…

C语言进阶——动态内存管理

目录 一. 为什么存在动态内存分配 二. 动态内存函数 1.malloc 2.free 3.calloc 4.realloc 三. 常见的动态内存错误 一. 为什么存在动态内存分配 在此之前&#xff0c;我们为数组开配空间都是这样的 int nums[10]{0}; 但这样会有很大的局限性 1. 空间开辟大…

十三、Gtk4-TfeTextView函数

TfeTextView相关函数在这一章节介绍 1 tfetextview.h 头文件tfetextview.h提供了: TfeTextView的类型&#xff0c;是TFE_TYPE_TEXT_VIEW。G_DECLARE_FINAL_TYPE的扩展包含了一些有用的宏。定义了open-response信号的常量。tfetextview.c的公共函数被声明。 因此&#xff0c…

「布道人生」第一期:阿里云DevOps资深专家章屹

本期嘉宾——章 屹 阿里云 DevOps 资深专家。2012 年加入阿里巴巴&#xff0c;十年如一日专注在 DevOps 领域的理论、咨询、解决方案和产品技术工作上。作为 CIO 学院和阿里云大学的讲师&#xff0c;为众多大型企业管理高层讲授 DevOps 课程&#xff0c;探讨通过 DevOps 提升企…

drawCell | 不会画细胞结构图就用这个R包吧~ Super Nice!~

1写在前面 我们在paper中经常需要画到细胞结构图&#xff0c;新手ppt一点一点画&#xff0c;高手可能会用AI手搓&#xff0c;土豪直接使用BioRender。&#x1f912; 今天给大家大家分享一个代码画细胞结构图的R包&#xff0c;如果你觉得自己不会写代码&#xff0c;不想看了&…

python基础篇之元组、字典(增删改查)

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

震旦ad188复印机报机器故障维修召唤c0211

故障现象: 手送走纸的机器出现嗒嗒的异响,走几张还会跳0211,经常出现卡纸等现象,或者报C0211; 故障分析: 维修召唤C0211可能是感光鼓和载体寿命到期࿰

云原生|Java二级高速缓存架构设计

为什么使用缓存 缓存&#xff0c;主要有两个用途&#xff1a;提高服务性能和并发。 缓存是提高服务响应速度最快的方式之一。 我们设计缓存的目的是减少用户直接访问磁盘、访问网络带来的性能损耗&#xff0c;把磁盘、网络请求的内容存在在内存中&#xff0c;提升应用程序的…

【Doris】Doris数据库最新版安装方法,详细图文教程

环境安装 Doris 作为一款开源的 MPP 架构 OLAP 数据库&#xff0c;能够运行在绝大多数主流的商用服务器上。为了能够充分运用 MPP 架构的并发优势&#xff0c;以及 Doris 的高可用特性&#xff0c;我们建议 Doris 的部署遵循以下需求&#xff1a; Linux 操作系统版本需求Linu…

研讨会回顾 | UI自动化测试现场演示

2022年12月6日&#xff0c;龙智与软件测试自动化“领导者”SmartBear联合举办了主题为“如何通过自动化测试实现降本、增效与提质”的在线研讨会。此次研讨会中&#xff0c;龙智技术工程师邱洁玉现场演示了使用UI自动化测试的过程&#xff0c;并简要介绍了API的自动化测试。 软…

时钟频率与时间单位的换算

1. 频率、时间 各自的单位的关系 频率&#xff1a; 1GHz 1000MHz、1MHz 1000KHz、1KHz 1000Hz 1GHz 103MHz 106KHz 109Hz 时间&#xff1a; 1s 1000ms、1ms 1000μs、1μs 1000ns [注]&#xff1a;s (秒)、ms (毫秒)、μs (微秒)、ns (纳秒)。 2. 时间 和 频率 的换…

jsp税务管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 税务管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发&#xff0c;数据库为Mysql&#xff0c;使用ja…