一. 事件背景

我最近运维了一个网上的实时接口服务,最近经常出现Address already in use (Bind failed)的问题。

很明显是一个端口绑定冲突的问题,于是大概排查了一下当前系统的网络连接情况和端口使用情况,发现是有大量time_wait的连接一直占用着端口没释放,导致端口被占满(最高的时候6w+个),因此HttpClient建立连接的时候会出现申请端口冲突的情况。

具体情况如下:

于是为了解决time_wait的问题,网上搜索了些许资料加上自己的思考,于是认为可以通过连接池来保存tcp连接,减少HttpClient在并发情况下随机打开的端口数量,复用原来有效的连接。但是新的问题也由连接池的设置引入了。

二. 问题过程

在估算连接池最大连接数的时候,参考了业务高峰期时的请求量为1分钟1.2w pv,接口平响为1.3s(复杂的广告推广效果模拟系统,在这种场景平响高是业务所需的原因)。

因此qps为12000*1.3\60=260

然后通过观察了业务日志,每次连接建立耗时1.1s左右, 再留70%+的上浮空间(怕连接数设置小出系统故障),最大连接数估计为2601.1*1.7约等于500。

为了减少对之前业务代码最小的改动,保证优化的快速上线验证,仍然使用的是HttpClient3.1 的MultiThreadedHttpConnectionManager,然后在线下手写了多线程的测试用例,测试了下并发度确实能比没用线程池的时候更高,然后先在我们的南京机房小流量上线验证效果,效果也符合预期之后,就开始整个北京机房的转全。结果转全之后就出现了意料之外的系统异常。。。

三. 案情回顾

在当天晚上流量转全之后,一起情况符合预期,但是到了第二天早上就看到用户群和相关的运维群里有一些人在反馈实况页面打不开了。这个时候我在路上,让值班人帮忙先看了下大概的情况,定位到了耗时最高的部分正是通过连接池调用后端服务的部分,于是可以把这个突发问题的排查思路大致定在围绕线程池的故障来考虑了。

于是等我到了公司,首先观察了一下应用整体的情况:

  • 监控平台的业务流量表现正常,但是部分机器的网卡流量略有突增
  • 接口的平响出现了明显的上升
  • 业务日志无明显的异常,不是底层服务超时的原因,因此平响的原因肯定不是业务本身
  • 发现30个机器实例竟然有9个出现了挂死的现象,其中6个北京实例,3个南京实例

四. 深入排查

由于发现了有近 1/3的实例进程崩溃,而业务流量没变,由于RPC服务对provider的流量进行负载均衡,所以引发单台机器的流量升高,这样会导致后面的存活实例更容易出现崩溃问题,于是高优看了进程挂死的原因。

由于很可能是修改了HttpClient连接方式为连接池引发的问题,最容易引起变化的肯定是线程和CPU状态,于是立即排查了线程数和CPU的状态是否正常

1、CPU状态

如图可见Java进程占用cpu非常高,是平时的近10倍

2、线程数监控状态:


图中可以看到多个机器大概在10点初时,出现了线程数大量飙升,甚至超出了虚拟化平台对容器的2000线程数限制(平台为了避免机器上的部分容器线程数过高,导致机器整体夯死而设置的熔断保护),因此实例是被虚拟化平台kill了。之前为什么之前在南京机房小流量上线的时候没出现线程数超限的问题,应该和南京机房流量较少,只有北京机房流量的1/3有关。

接下来就是分析线程数为啥会快速积累直至超限了。这个时候我就在考虑是否是连接池设置的最大连接数有问题,限制了系统连接线程的并发度。为了更好的排查问题,我回滚了线上一部分的实例,于是观察了下线上实例的 tcp连接情况和回滚之后的连接情况

回滚之前tcp连接情况:

回滚之后tcp连接情况:

发现连接线程的并发度果然小很多了,这个时候要再确认一下是否是连接池设置导致的原因,于是将没回滚的机器进行jstack了,对Java进程中分配的子线程进行了分析,总于可以确认问题。

jstack状态:

从jstack的日志中可以很容易分析出来,有大量的线程在等待获取连接池里的连接而进行排队,因此导致了线程堆积,因此平响上升。由于线程堆积越多,系统资源占用越厉害,接口平响也会因此升高,更加剧了线程的堆积,因此很容易出现恶性循环而导致线程数超限。

那么为什么会出现并发度设置过小呢?之前已经留了70%的上浮空间来估算并发度,这里面必定有蹊跷!

于是我对源码进行了解读分析,发现了端倪:

如MultiThreadedHttpConnectionManager源码可见,连接池在分配连接时调用的doGetConnection方法时,对能否获得连接,不仅会对我设置的参数maxTotalConnections进行是否超限校验,还会对maxHostConnections进行是否超限的校验。

于是我立刻网上搜索了下maxHostConnections的含义:每个host路由的默认最大连接,需要通过setDefaultMaxConnectionsPerHost来设置,否则默认值是2。

所以并不是我对业务的最大连接数计算失误,而是因为不知道要设置DefaultMaxConnectionsPerHost而导致每个请求的Host并发连接数只有2,限制了线程获取连接的并发度(所以难怪刚才观察tcp并发度的时候发现只有2个连接建立

HttpClient 设置不当引发的一次雪崩相关推荐

  1. HttpClient 设置不当引发的一次雪崩!

    作者 | zxcodestudy 来源 | https://blog.csdn.net/qq_16681169/article/details/94592472 一. 事件背景 我最近运维了一个网上的 ...

  2. HttpClient 连接池设置不当引发的一次雪崩

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | zxcodestudy 来源 | http:/ ...

  3. HttpClient设置请求超时

    前言 最近,我无疑间看到同事提交到git上的httpclient调用第三方服务设置超时代码,发现有趣的一件事.项目中引用的httpclient版本是4.4.5版本,结果同事为了设置超时,在项目的pom ...

  4. 网络营销专员表示网络营销中设置不当会影响蜘蛛爬虫对网站抓取

    在日常网站优化中如果想要网站拥有良好的网站排名,就要针对搜索引擎的抓取习惯培养友好度和信任度,网站在运营优化中难免会发生因为一些细节问题影响蜘蛛爬虫对网站正常抓取,那么究竟哪些操作设置会影响蜘蛛爬虫对 ...

  5. 如何在并发中给 HttpClient 设置不同的超时时间?

    咨询区 boot4life 为了能够复用 HttpClient 所打开的TCP链接,我不得不让所有的request共享一个单例,但问题来了,如果我简单的在每一次request之前修改 timeout ...

  6. android HttpClient 设置代理

    HttpClient client = new HttpClient();//设置代理.转发到 哪个 ip 和 port , 192.168.3.196 是我本机的charles 地址和端口clien ...

  7. CMOS设置不当引起的故障排除

    主板的故障千奇百怪,虽然大部分时候电脑无法正常启动是由主板硬件损坏所导致的,但由于设置不当所造成的无法正常启动故障也不少见.我们知道,主板的BIOS也是整个系统的BIOS,如果设置不当,便可以出现这样 ...

  8. raid配置ssd为缓存_SSD并不可怕 设置不当掉速毁盘才可怕

    1SSD读写狂飙 如何设置不掉速 SSD固态硬盘如今成为装机配置中的必选产品,动辄500-600MB/秒的读写速度,可能因为主板.SSD设置不对,SSD的性能没有真正发挥出来.硬盘掉速问题最早来源于机 ...

  9. dhcp服务器连接状态,DHCP设置不当故障的解决方法

    DHCP设置不当故障的解决方法 发布时间:2012-11-12 14:21:52   作者:佚名   我要评论 DHCP设置不当,造成部分终端不能正常从DHCP服务器那里获得有效的上网参数.现在,本文 ...

  10. HttpClient连接池设置引发的一次雪崩

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://i7q.cn/50G6cx - 1 - 事件背 ...

最新文章

  1. ATAC-seq【Harvard FAS Informatics】
  2. [课堂实践与项目]NavigationController与TabBarController的综合使用及易错点分析(包含消息提醒,app更新)...
  3. Webex 如何在在线会议领域保持优势?
  4. MATLAB中三维曲面命令
  5. asynchttpclient 超时_英雄联盟手游登录超时解决办法 登录超时如何解决_游戏花边...
  6. IDC发布2020上半年SD-WAN报告:阿里云领跑国内服务市场
  7. 遗传算法的C语言设计
  8. Itext7 jar 下载 链接
  9. jQuery选择器 第六章
  10. python spss_SPSS python教程:[5]SpssClient简介
  11. 使用 IDEA 文件统计工具 Statistic
  12. 最近3年股息率最高排名
  13. 使用大白菜装win10系统的常见问题解决方案
  14. Allure报告的安装及环境变量的配置和在pytest中调用
  15. uni-app 应用换肤功能
  16. JavaScript几种原生函数
  17. 对象到底是怎么new出来的
  18. 如何用70行Java代码实现深度神经网络算法
  19. 服务器、虚拟主机和空间的区别
  20. 9.8.1 1.打印head标签的内容。2.打印body标签的内容。3.打印id为Hi的标签对象

热门文章

  1. Java:面向对象编程
  2. mfc 服务器文件拷贝到本地,mfc服务器客户端间传输文件
  3. 计算机社团招新个人简历,大学社团招新面试自我介绍五篇
  4. System.IndexOutOfRangeException: 无法找到表 0解决办法
  5. dedecms读取多个类别信息
  6. [论文评析] ArXiv-2021,Pyramid Vision Transformer A Versatile Backbone for Dense Prediction without Convo
  7. node.js(一)基础介绍
  8. 图像/视频超分之BackProjection
  9. Kotlin 丢失了一些 JRE 类
  10. 半个月使用rust语言的体验