记一次中间件宕机以后持续请求导致应用OOM的排查思路(server.max-http-header-size属性配置不当的严重后果)

一、背景

最近有一次在系统并发比较高的时候,数据库突然发生了故障,导致大量请求失败,在数据库宕机不久,通过应用日志可以看到系统发生了OOM

二、排查

初次看到这个现象的时候,我还是有点懵逼的,数据库宕机以后为什么会导致应用发生OOM呢?

不管怎么样,先按照传统思路,分析一下应用此时的dump文件。

通过MemoryAnalyzer工具进行dump文件分析,通过Leak Suspects页面可以发现,有两个可以点,如下:

在这里插入图片描述

system class loader看起来没有什么问题,org.apache.coyote.http11.Http11OutputBuffer对象占用这么多内存倒是真的可疑。

打开MemoryAnalyzer工具Dominator Tree页面,过滤org.apache.coyote.http11.Http11OutputBuffer,截图如下:

在这里插入图片描述

可以看到,内存中有大量org.apache.coyote.http11.Http11OutputBuffer对象,同时每个对象都持有一个2048000长度的字节数据。

通过在IDEA中对org.apache.coyote.http11.Http11OutputBuffer对象的引用发现,Http11OutputBuffer是用于tomcat处理请求时,用于每个请求处理时都会生成,代码如下:

org.apache.coyote.http11.Http11Processor#Http11Processor

在这里插入图片描述

进入protocol.getMaxHttpRequestHeaderSize()方法:

在这里插入图片描述

进入getMaxHttpHeaderSize()方法:

在这里插入图片描述

可以看到maxHttpHeaderSize属性值默认是8192字节,怎么变成了上面的2048000长度了呢?

通过debug代码可以发现,在org.springframework.boot.autoconfigure.web.embedded.TomcatWebServerFactoryCustomizer#customizeMaxHttpHeaderSize方法中会进行覆盖设置,如果你在配置文件中配置了server.max-http-header-size属性,那么maxHttpHeaderSize默认的8192就会被覆盖。

同时,根据org.apache.coyote.http11.Http11Processor#Http11Processor源码,发现每次请求时也都会创建org.apache.coyote.http11.Http11InputBuffer对象,于是我又在MemoryAnalyzer工具Dominator Tree页面搜索了Http11InputBuffer类,如下:

在这里插入图片描述

此时,我发现为什么Http11InputBuffer对象持有的buffer大小不是2048000而是2056192,整整大了8192呢?

通过debug可以发现,答案可以在org.apache.coyote.http11.Http11InputBuffer#init方法中找到:

在这里插入图片描述

Http11InputBuffer对象中,buffer大小除了设置的size之外,还会加一个wrapper.getSocketBufferHandler().getReadBuffer().capacity(),通过代码调试可以发现,SocketBufferHandler的设置在org.apache.tomcat.util.net.NioEndpoint#setSocketOptions方法中进行的:

在这里插入图片描述

进入org.apache.tomcat.util.net.SocketProperties可以发现,buff的默认大小就是8192:

在这里插入图片描述

此时,问题排查基本结束了,排查中遇到的疑问也基本解决了。

三、原因

通过上面的分析可以发现,由于有人在配置文件中设置了server.max-http-header-size属性,

server:
  max-http-header-size: 2048000

覆盖了默认的8KB大小,导致每次请求创建的Http11InputBufferHttp11OutputBuffer对象持有的buffer大小增加到2MB,在数据库宕机以后,tomcat还在继续接受请求,由于请求响应阻塞,同时此时会有大量请求进行堆积,但是每次请求都会创建Http11InputBufferHttp11OutputBuffer对象,同时会向JVM申请内存,导致JVM内存使用量急剧增加,从而导致OOM

四、问题解决

找到问题原因以后,有点好奇,为什么要修改server.max-http-header-size属性呢?通过内部排查得知,原来是应用提供的某个接口是GET请求方式,在请求URL中拼接的参数过大的时候会报Request header is too large异常信息。

看到这个异常信息有点奇怪,为什么GET请求会有这个错误呢,为什么修改server.max-http-header-size属性可以解决呢?通过代码debug发现,Http11InputBuffer对象其实处理的是整个请求报文,包括请求头请求行等信息,所以GET方式请求URL大小和请求头大小都会被Http11InputBuffer对象持有的buffer大小限制,因此修改server.max-http-header-size属性确实可以解决GET请求方式由于URL过长导致的Request header is too large异常问题。

最后,将该GET请求方式接口修改成了POST方式请求,参数传递也通过请求体进行,删除配置文件中

server.max-http-header-size属性配置,恢复默认值8192,在测试环境进行测试,发现OOM问题可以解决。不过,虽然程序层面问题解决了,不过数据库稳定性问管理还需要进一步加强。

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

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

相关文章

解决方案ImportError: cannot import name ‘BertTokenizerFast‘ from ‘transformers‘

文章目录 一、现象二、解决方案 一、现象 从transformers 库调用该包的时候 from transformers import BertTokenizer, AdamW, BertTokenizerFast报错显示 ImportError: cannot import name ‘BertTokenizerFast’ from ‘transformers’ 二、解决方案 追溯查看transforme…

人工智能论文GPT-3(1):2020.5 Language Models are Few-Shot Learners;摘要;引言;scaling-law

摘要 近期的工作表明,在大量文本语料库上进行预训练,然后针对特定任务进行微调,可以在许多NLP任务和基准测试中取得实质性进展。虽然这种方法在架构上通常是与任务无关的,但仍然需要包含数千或数万示例的针对特定任务的微调数据集…

【解决】Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed

问题原因: 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 解决方案: 我使用的是忽略证书验证 public clas…

面试算法-173-二叉树的直径

题目 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1: 输入:root [1,2,3,4,…

水电预付费系统多少钱?

一、水电预付费系统的定义与优势 水电预付费系统是一种现代化的管理方式,它颠覆了传统的后付费模式,让用户在使用水电前先进行支付。这种系统通常包括智能电表、充值终端、后台管理系统等组成部分,通过自动化处理,实现费用的预先…

MATLAB实现蚁群算法优化柔性车间调度(ACO-fjsp)

蚁群算法优化车间调度的步骤可以分为以下几个主要阶段: 1.初始化阶段: 设置算法参数,如信息素浓度、启发式因子等。这些参数将影响蚂蚁在选择路径时的决策过程。 确定车间调度的具体问题规模,包括工件数量、机器数量以及每个工件…

通过Docker新建并使用MySQL数据库

1. 安装Docker 确保您的系统上已经安装了Docker。可以通过以下命令检查Docker是否安装并运行: systemctl status docker如果没有安装或运行,请按照官方文档进行安装和启动。 2. 拉取MySQL镜像 从Docker Hub拉取MySQL官方镜像。这里以MySQL 5.7版本为…

【数学】深度学习中的概率基础知识记录

基于 Deep Learning (2017, MIT) 书总结了必要的概率知识 原blog 以及用到的Ipython notebook 文章目录 1 概述2 知识2.1 离散变量和概率质量函数(PMF)2.2 连续变量和概率密度函数(PDF)2.3 边缘概率2.4 条件概率2.5 条件概率的链式…

Qt gsl库配置踩坑记录

想求解非线性方程组,之前使用拟牛顿法写过相关的matlab代码,这次想移植到C代码,网上说gsl库挺好用的,于是我也想试一下。相关参考: 【C】GSL(GNU Scientific Library) 的安装及在 Visual Studio 2017 中的使用 QT5使用…

k8s部署Eureka集群

部署有状态负载 镜像配置: 环境变量如下: AUTHENTICATE_ENABLEtrue JAVA_OPTS-Dauth.userName账号 -Dauth.password密码 MY_POD_NAMEmetadata.name BOOL_REGISTERtrue BOOL_FETCHtrue APPLICATION_NAME负载名称 EUREKA_INSTANCE_HOSTNAME${MY_POD_NA…

单臂路由实验

单臂路由是一种在单个物理接口上配置多个逻辑接口,以实现不同VLAN间通信的技术。它通过在路由器接口上划分子接口,每个子接口对应一个VLAN网段,从而实现了VLAN间的互联互通。单臂路由能够重新封装MAC地址,转换VLAN标签&#xff0c…

1.微服务介绍

完整的微服务架构图 注册中心 配置中心 服务集群 服务网关 分布式缓存 分布式搜索 数据库集群 消息队列 分布式日志服务 系统监控链路追踪 Jenkins docker k8s 技术栈 微服务治理: 注册发现、远程调用、负载均衡、配置管理、网关路由、系统保护、流量…

(mac)性能监控平台搭建JMeter+Grafana+Influxdb

【实现原理】 通过influxdb数据库存储jmeter的结果,再通过grafana采集influxdb数据库数据,完成监控平台展示 一、时间序列数据InfluxDB 1.InfluxDB下载安装 官网下载 https://portal.influxdata.com/downloads/ 官网最新版: &#xff0…

计算机网络1-TCP和UDP

TCP与UDP 同:都工作在传输层,目标都是在程序间传输数据(文本、视频等等),都是2进制数据; 区别: TCP:电话,基于连接, UDP:书信,基于非…

Golang图像处理实战:image/png包的应用详解

Golang图像处理实战:image/png包的应用详解 介绍基本操作读取PNG文件保存PNG文件 处理图像数据修改图像像素图像裁剪和缩放 高级功能使用 image/color 处理颜色优化PNG性能 错误处理与调试常见错误及其解决方法文件无法打开图像解码失败 使用工具和库进行调试 结语 …

软航H5 PDF签章产品经nginx代理之后浏览器中PDF盖章时提示:签章失败:网络错误 的问题排查及解决办法

目录 问题现象 问题排查思路 问题处理办法 附:软航H5 PDF签章产品介绍 软航电子签章系统 软航版式文档签批系统 问题现象 问题描述:在系统中集成了软航H5 PDF签章产品,软航H5 PDF签章产品的对应服务是通过nginx代理的,在奇安…

微信小程序地图polyline坐标太多异常显示BUG

描述 微信小程序map地图上显示polyline线,点位超过1250个出现bug,(仅真机上出现,模拟器上正常) 这里以加载四川省边界为例, 以下是示例代码 // 读取geojson数据 uni.request({url: https://geo.datav.aliyun.com/a…

公网IP地址如何申请SSL证书?有免费的IP ssl吗?

如果用户没有域名或只有公网IP地址或者不方便使用域名,IP地址ssl证书这一特殊的证书可以为IP地址实现HTTPS的安全保护,提高网站数据传输的安全性。 IP地址申请SSL证书的基本步骤 IP ssl证书下载---注册填写230916https://www.joyssl.com/certificate/sel…

CalcPad(2) 单位设置和绘制图表

CalcPad(2) 单位设置和绘制图表 Hi uu们,CalcPad用的还好吗?有发现一些问题吗? 在我的使用中,经常需要指定一些计算结果的符号,比如说我希望ADC最小分辨率的计算结果是以uV展示,那我们该怎么操作呢&#…

x-cmd mod | x whisper - 使用 whisper.cpp 进行本地 AI 语音识别

介绍 Whisper 模块通过 whisper.cpp 帮助用户快速将音频转换为文字。 INFO: whisper.cpp 是一个用 C/C 编写的轻量级智能语音识别库,是基于 OpenAI 的 Whisper 模型的移植版本,旨在通过深度学习模型实现音频转文字功能。 由于 whisper.cpp 目前只支持 1…
最新文章