connect reset/timeout/reject 排查

异常排查

  • 问题描述
  • 问题处理
    • 初步分析
    • http配置即服务整体情况
    • 整体排查
      • 服务重启
      • gc
      • CPU
      • JVM
  • 暂存疑问点
  • 总结
    • 启动参数要配全
    • 监控体系健全
    • 科学使用jar包
    • 降配参数是参数得动态变

问题描述

最初出现的时候,是在每天的早上8-10这个时间范围内,服务A上的有一个接口时不时报警,内容不一,有 connect timeoutconnect resetconnect reject等,其中connect reject比较频繁。在后续观察中,发现tomcatnio线程一般正常运行下为100以下,但是在异常重启前一个小时内会飙升至1000也就是配置的最大线程数。

问题处理

初步分析

线上部署的服务A有4个pod,每台机器的配置是1g。是springboot项目,tomcat配置如下

server:
  tomcat:
    uri-encoding: UTF-8 
    accept-count: 1000
    max-connections: 2000
    max-threads: 1000
    min-spare-threads: 10
  connection-timeout: 60000

乍一看线程数量有一点多。之后看了一下是不是有问题的接口逻辑,主要交互节点如下

1、接收请求,根据token查缓存获取用户数据
2、feign调用用户服务获取用户信息
3、根据获取的信息查数据库,然后组装结果返回

整体逻辑看着也很简单,feign调用耗时也不是很高。查缓存的话,应该也没有问题,不然就单是一个服务的问题了。那就是查库的问题了,我把执行sql分析了一下,走了索引,表的数据量也不是很大,那是哪一步出问题了。。

http配置即服务整体情况

接口处理时间变长的一种情况是,并发请求太大,导致服务请求处理不过来(如果接口有限流配置那么其实就直接拒掉了,这个服务没有配置)。我在ES上看了一个服务的峰值请求量,秒级不超过一千。异常接口峰值秒级也只有3、4百,分到每台机器上也就100多,1000个线程怎么都处理的过来吧。除非其他接口请求量也大,而且处理时间长,占用了线程。但是我在ES上看了一下接口处理耗时,报警的那一会的确有耗时变长的情况,请求量的确也有所上升。
此外,我看了一个物理机的tcp配置

net.core.somaxcon  // 128
net.ipv4.tcp_max_back_log  // 1000

这两配置有点小了。

此时,我的推测如下:

1、connect timeout 是因为处理请求不过来
2、connect reset 是因为 http全连接 半连接池太小,被请求占满导致
3、connect reject 服务不可用

经过灰度测试,发现不明显。connect reject 仍出现。

整体排查

服务重启

connect reject出现的原因,理论上是服务寄了。但是怎么能知道它寄没寄呢。突然想到,这个服务有注册到注册中心,也就是eureka。上去一下,没有下线信息,但是报错那个时间点有上线信息。

在这里插入图片描述

于是,推测那个时间点是不是服务重启了。看了一下线上服务的日志,发现日志归档了,gc信息也归档了。然后看技术上线记录,发现没人手动上线,于是推测是服务自动重启,然后找运维确定了一下,的确有重启记录。容器默认配置3分钟内5次心跳没通过重启。。

gc

gc信息
将运行时的gc日志文件分析后,发现gc很频繁。而且full gc后内存下降不是很明显。但是gc停顿时间最长就1.7秒,不可能3秒内都不可用,所以gc有问题,但可能不是主要问题。

CPU

jvm和cpu使用情况

可以看到,使用情况还是挺高的。具体看进行的CPU情况,发现基本是在100%。

// 看进行下哪个线程使用的cpu比较高
top -Hp 进程id 
// 10进制 转为 16进制
printf '%x\n' 线程id
// 定位线程的信息  d8为上面转换后的16进制
jstack 进程id | grep '0xd8' 

jstack信息

这里拍的有点糊哈,最终定位到是 AsyncReporter 190行代码,我这里zipkin版本是2.7.10,对应的就是flush节点。
这里服务配置的是zipkin收集方式是kafka,大小是默认的1000000,可以认为是1M,时间的话配置了60s’.

在这里插入图片描述

然后在线上用arthas看了一下方法运行信息
在这里插入图片描述

最后推测出可能是AsyncReporter265行的问题,因为一直没到配置的最大大小(1M),导致一直在死循环。

// ByteBoundedQueue#offer   131行
@Override
public boolean offer(S next, int nextSizeInBytes) {
  int x = messageSizeInBytes(nextSizeInBytes);
  int y = maxBytes;
  int includingNextVsMaxBytes = (x < y) ? -1 : ((x == y) ? 0 : 1); // Integer.compare, but JRE 6

  if (includingNextVsMaxBytes > 0) return false; // can't fit the next message into this buffer

  addSpanToBuffer(next, nextSizeInBytes);
  messageSizeInBytes = x;

  if (includingNextVsMaxBytes == 0) bufferFull = true;
  return true;
}
// 这里可以看到,只有刚好填充满,bufferFull才可能等于true
// BoundedAsyncReporter#flush()  
void flush(BufferNextMessage<S> bundler) {
      if (closed.get()) throw new IllegalStateException("closed");

      pending.drainTo(bundler, bundler.remainingNanos());

      // record after flushing reduces the amount of gauge events vs on doing this on report
      metrics.updateQueuedSpans(pending.count);
      metrics.updateQueuedBytes(pending.sizeInBytes);

      // loop around if we are running, and the bundle isn't full
      // if we are closed, try to send what's pending
      if (!bundler.isReady() && !closed.get()) return;
      
      // ...省略
}      

// 这里的  bundler.isReady() 判断逻辑如下
boolean isReady() {
   return bufferFull || remainingNanos() <= 0;
 }
 // 也就是说,如果时间没到,且没满,那么返回false,此时 flush方法return。这样就开始死循环了,类似while(true)。
 // 如果超时时间比较短,例如默认的1s,那其实也能接受。但是这里我们自己改了默认值,配置了60s,
 // 也就是说在这一分钟内,如果大小刚好卡死,例如当前buffer使用了950kb,下一个100kb,
 // 两者相加不等于1000kb,此时剩余时长都在死循环,CPU自然使用率高了。

修改配置,变为默认值后灰度发布

优化后的代码

这里可以看到,明显降低了,使用率基本在1%左右,原先都是10%以上。。后面去看了一下最新版本实现,发现这个bug已经修复了。

在这里插入图片描述

可以看到,这里大于最大值后也会认为满了,而不是一定要等于最大值。。

JVM

一天堆和非堆使用情况

可以看到,这里的堆使用也不能说有啥大的问题,最多full gc有点多吧,相对而言。但是非堆的话,明显感觉有点问题,理论上来说应该是稳定的。它这里有起伏。

arthas看内存使用情况

后面用arthas执行memory看了一下内存使用情况,发现没设置mataspace的大小。所以理论上来说它可以无限占用物理机内存。图片可以看到,目前已经用了1.9g了,不太合理。
metaspace主要放的是类的信息,所以推测是不是在运行过程中在动态创建类。dump线上的堆栈信息,用visualvm打开。默认是类实例数正向排序的。

默认visualvm打开

这么看其实看不出啥问题,最多会看看类实例多的是不是内存泄露了。但这次我们得反向排序,因为matespace异常大,说明类都是不一样的。

根据实例数倒排

这么一看,是不是明显发现问题了。都是Script_前缀开头的。本地起一下项目,用arthas找一下类信息 sc -d -n 10 Script_*

arthas筛选定位类

这里看到是aviator,它是谷歌开发的一个表达式引擎。在代码里全局搜了一下,发现就一个地方在使用,看了一下具体内容,发现是没有开启缓存导致反复创建代码。

使用地方
在这里插入图片描述

改为之后,灰度发布,过一天运行结果

修复后内存使用情况

这里可以看到,非堆使用基本稳定了,堆使用也基本平滑了。但是那两次异常GC看着还有点问题。

暂存疑问点

1、最后平稳后的gc原因,是什么触发的。
2、tomcat线程数异常飙升的原因 是因为metaspace没法分配空间导致线程阻塞么。。
3、服务重启的原因 nio处理线程都被阻塞了,导致心跳接口没人处理么。。

总结

启动参数要配全

像gc具体信息、最大mataspace大小、OOMdump等配置参数最好都加上,不然出现问题了手上都没啥资料。。

监控体系健全

有良好的监控,分析问题起来事陪功半。一开始没有cpu、堆等使用的监控图表,光靠脑子想还是太抽象了

科学使用jar包

使用开源jar包,最好自己看一下实现方法,别直接拿来用。不然坑了自己都不知道

降配参数是参数得动态变

1g内存配了1000个线程,有点不太合理了吧。降配不能单单改内存,其他配置也得一起变化。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电源方案对比

电源 1.方案选择&#xff1a;1 LM2596 2 MP1584 3&#xff1a;TPS54301LM25962.MP1584&#xff1a;3.TPS5430 2.1输出2A电流的纹波2.2 输出3A电流的纹波3.动态响应4.发热5.电源转换效率6.综合指标reference 1.方案选择&#xff1a;1 LM2596 2 MP1584 3&#xff1a;TPS5430 1LM…

开源赋能 普惠未来|XuperCore诚邀您参与2023开放原子全球开源峰会

XuperCore&#xff08;待更名&#xff09;是百度自主研发&#xff0c;拥有完整知识产权的区块链底层技术XuperChain的内核&#xff0c;拥有620多篇区块链核心技术专利&#xff0c;以“高性能”、“开源”为主要设计目标&#xff0c;致力于创建“更快、更通用、更好用”的区块链…

protobuf全局环境搭建

一、安装npm 1.测试是否安装npm 如果未出现npm 不是内部或外部命令&#xff0c;则先安装npm npm是NodeJs的包管理器&#xff08;Node Package Manager&#xff09; 所以我们要安装npm&#xff0c;其实就是安装NodeJs&#xff0c;进入NodeJs官网 下载完成之后&#xff0c;安装…

开发工具---Eclipse 教程Ⅰ

Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。 Eclipse 是 Java 的集成开发环境&#xff08;IDE&#xff09;&#xff0c;当然 Eclipse 也可以作为其他开发语言的集成开发环境&#xff0c;如C&#xff0c;C&#xff0c;PHP&#xff0c;和 Ruby 等。 Eclipse 附带…

劝你别去外包,干了三年,感觉废了一半....

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

【Android定制】BUILD_AGO_GMS = no 和 BUILD_GMS=no属性

文章目录 概要名词解释细节小结 概要 在安卓底层源码中&#xff0c;有这样的两个属性&#xff0c;这两个第一眼看上去都像是带不带谷歌&#xff0c;BUILD_AGO_GMS no和BUILD_GMSno有什么区别&#xff1f;&#xff1f; 如果带了谷歌&#xff0c;那么这个设备就差不多是国外定…

小程序极速注册认证免300认证费 突破管理员身份只能绑定5个小程序绿色通道

小程序注册账号管理相信大家有时候头都很大&#xff0c;一个身份证号只能绑定5个小程序主管理员。超个5个小程序就得请朋友、请亲戚身份证绑定管理员。有时还得看对方不方便&#xff0c;改个类目改个LOGO都还得管理员扫码。为了满足会员需求同是也满足自己需要&#xff0c;特别…

陌生交友发布动态圈子单聊打招呼群聊app开发

陌生交友发布动态圈子单聊打招呼群聊app开发 功能有&#xff0c;发布圈子&#xff0c;发布动态&#xff0c;查看附近的人&#xff0c;发布活动&#xff0c;实人认证&#xff0c;个人主页&#xff0c;相册查看,单聊&#xff0c;群聊。 即时通讯第三方goeasy接口。 好的&#x…

【nginx】同一接口有时返回500(client_body_temp)

问题描述&#xff1a; 同一个接口&#xff0c;有能正常访问并返回的&#xff0c;有的访问未到服务器直接返回500。 查看nginx日志&#xff08;error.log&#xff09;&#xff0c;发现open() "/nginx/client_body_temp/0000476534" failed (13: Permission denied)报…

Linux——makefile自动化构建工具

一. 前言 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的 规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;甚至于进行更复杂 的功能…

Navicat “1205 - Lock wait timeout exceeded; try restarting transaction“

标题标题&#xff1a;解决Navicat数据库操作报错&#xff1a;1205 - Lock wait timeout exceeded; try restarting transaction 导言&#xff1a; 在使用Navicat进行数据库操作时&#xff0c;有时会遇到错误代码为"1205 - Lock wait timeout exceeded; try restarting t…

论文分享 A ConvNet for the 2020s

摘要 视觉识别的“咆哮的 20 年代”始于 Vision Transformers (ViTs) 的引入&#xff0c;它迅速取代了 ConvNets&#xff0c;成为最先进的图像分类模型。另一方面&#xff0c;vanilla ViT 在应用于对象检测和语义分割等一般计算机视觉任务时面临困难。正是层次化的 Transforme…

蓝奥声核心技术分享——无线同步群控技术

1.技术背景 无线同步群控技术指基于对目标场景状态变化的协同感知而获得触发响应并进行智能决策&#xff0c;属于蓝奥声核心技术--边缘协同感知(EICS&#xff09;技术的关键支撑性技术之一。该项技术涉及无线物联网边缘域网络的无线通信与智能控制技术领域&#xff0c;具体主要…

【2023 · CANN训练营第一季】昇腾AI入门课(TensorFlow)第三章——AI应用开发

1.具备编程经验 本课程中的示例代码、练习涉及C&C语言、Python语言的如下基础知识&#xff0c;建议您在学习本课程前先学习这部分内容 1.C&C语言 a.变量、基本数据类型、指针、引用、const限定符等 b&#xff0c;字符串和数组 c.表达式&#xff0c;包括赋值运算、条件…

华为OD机试真题 Java 实现【统计匹配的二元组个数】【2023Q2 200分】

一、题目描述 给定两个数组A和B&#xff0c;若数组A的某个元素A[i]与数组B中的某个元素B[j]满足 A[i] B[j]&#xff0c;则寻找到一个值匹配的二元组(i, j)。 请统计在这两个数组A和B中&#xff0c;一共存在多少个这样的二元组。 二、输入描述 第一行输入数组A的长度M&…

python---变量(2)

此处&#xff0c;首次使用“”对a进行设置值&#xff0c;也就是对a的初始化。 后续位置对a使用“”&#xff0c;实际上是对a赋值。 因此两行代码得到的结果显然是不同的&#xff01; 变量的种类 1.整数-int-根据数据大小自动扩容 python中的变量类型不需要显示声明&#…

9:00进去,9:05就出来了,这问的也太变态了···

从外包出来&#xff0c;没想到死在另一家厂子了。 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到5月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推…

扬帆起航——Qt自定义控件介绍

文章目录 前言自定义控件的定义自定义控件的好处如何实现自定义控件实现没有自带的控件 如何使用自定义控件测试和优化常见的自定义控件总结 前言 Qt 提供了丰富的控件、工具和库&#xff0c;可以帮助开发人员快速创建现代化的跨平台应用程序。但是对于某些特殊的需求&#xf…

Fourier分析入门——第7章——采样理论

目录 第 7 章 采样定理 7.1 引言 7.2 采样定理 7.3 错误识别(aliasing) 7.4 Parseval定理(Parseval[pzeifa:l]) 7.5 截断Fourier级数和回归理论(Truncated Fourier Series & Regression Theory) 第 7 章 采样定理 7.1 引言 在第 6 章中&#xff0c;我们发现有限区…

【大数据学习篇10】Spark项目实战~网站转化率统计

学习目标/Target 掌握网站转化率统计实现思路 了解如何生成用户浏览网页数据 掌握如何创建Spark连接并读取数据集 掌握利用Spark SQL统计每个页面访问次数 掌握利用Spark SQL获取每个用户浏览网页的顺序 掌握利用Spark SQL合并同一用户浏览的网页 掌握利用Spark SQL统计每…