NO.33 要你命3000-宕机问题面面观 4.案例-获取全表数据致OOM

本文记述了一次因不当SQL查询导致的应用OOM故障排查过程。通过对JVM内存使用情况的实时监控,结合对驻留SQL的分析,最终定位到问题根源,并给出了相应的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

    某年某月,这个月里发生了几次应用OOM,时间上一般发生在业务繁忙期(应用采用SUN JDK1.4.2.18 -Xmx2560m,一般观察繁忙期的JVM消耗最多也就到500m)。

    总算有一次实时观察JVM内存图时(NO.28宕机问题定位分析法 2.查看JVM监控图),重现了OOM现场:JVM消耗在不到一分钟里从400m冲到了上限。赶在JVM到顶前看了下URL访问表(NO.28宕机问题简单定位分析法 1.1查看长时驻留的请求URL),发现了一个驻留时间比较长的URL,抽丝剥茧,找到一段这样的代码:

 

    where 后面跟1=1,这样SqlUtils.convertString如果返回条件前面可以直接加上"and"

    SqlUtils.convertString有这么个规则:如果aColumnValuenull或空串,则其返回值为空串

    一查,aHugeTable 76多万笔数据......

    因此,初步判断(其实基本上是一定的了)aColumnValue为空……

    拉过来写这段代码的人,说页面上有JS校验,不可能传过来空值,我说校验的事你再去查,考虑到aColumn有索引,你先把那个语句改成这样,赶紧升级:

    紧接着,在更新环境之前,查看DBManager驻留的SQL(还好,系统还没有死干净,这个页面还能看的到),找到了“select ###### from aHugeTable where 1=1”,终100%验证了当初的推断。

    (之前,因为硬件问题,不能使用P6SPY(一种监控JDBCSQL的组件),因此自己改造了连接管理器类(DBManager),也实现了当SQL执行时间超过指定的阀值时,输出到一个文本中。这样做还是有个缺陷:没有执行完毕的是无法记录下来的,其实这些没执行完的很可能就是超级长时SQL。所以这个改造是必然的:每隔N秒,将DBmanager中当前执行的SQL刷新到一个文本中,这样一来,就没必要通过一个URL请求去看这些驻留SQL了:)

 

<think>好的,我现在需要处理用户关于“spring.codec.max-in-memory-size”的查询。首先,我得回忆一下这个配置的作用。记得在Spring框架中,特别是Spring WebFlux,这个参数是用来限制编解码器在处理HTTP请求和响应时的内存使用的。当上传或下载的数据量较大时,这个参数可以防止内存被耗尽,从而提高应用的稳定性。 接下来,用户可能想知道如何配置这个参数。我需要确认在Spring Boot的不同版本中,配置的方式是否一致。一般来说,在application.properties或application.yml文件中设置,但需要给出具体的例子。比如,在properties文件中使用spring.codec.max-in-memory-size=10MB,或者在YAML中的正确格式。 然后,用户可能关心默认值的问题。不同版本的Spring Boot可能有不同的默认值,比如旧版本默认可能是256KB,而新版本可能调整到了更大的值,比如2MB。需要查阅最新的文档来确认这一点,确保信息的准确性。 另外,应用场景也是需要解释的。比如,当处理大文件上传或下载时,如果超出内存限制,会抛出DataBufferLimitException,这时候调整这个参数可以解决问题。但也要提醒用户注意,设置过大可能导致内存压力,需要权衡。 可能还需要提到,除了全局配置,Spring是否支持针对不同接口单独设置内存限制。比如,在WebFlux中,可以通过ServerCodecConfigurer在配置类中进行更细粒度的控制,这样用户可以根据具体需求调整特定路由的设置。 最后,要确保回答结构清晰,分点说明,同时避免使用Markdown,用自然的中文口语化表达。需要检查是否有遗漏的信息点,比如相关的异常类型、配置的位置、版本差异等,确保用户能够全面理解这个参数的作用和使用方法。</think>在Spring框架中,`spring.codec.max-in-memory-size`是一个用于**控制编解码器内存缓冲大小**的关键配置属性,主要应用于Spring WebFlux(响应式Web模块)。以下是逐步说明: --- ### 一、作用解析 1. **内存限制** 当Spring处理HTTP请求/响应的编解码(如解析JSON、XML或文件上传)时,会预先分配内存缓冲区。此属性设定了单个数据块(如一个文件或一个字段)**允许占用的最大内存**。超出限制时,数据会被写入磁盘临时文件,避免内存溢出(OOM)。 2. **适用场景** - 上传/下载大文件 - 处理包含大型Base64编码数据的请求体 - 解析内存敏感的高并发请求 --- ### 二、默认值与配置方式 1. **默认值** - Spring Boot 2.x 默认值为 **256KB** - Spring Boot 3.x 调整为 **2MB** 2. **自定义配置** 在`application.properties`或`application.yml`中设置: ```properties # 示例:设置为10MB spring.codec.max-in-memory-size=10MB ``` ```yaml # YAML格式 spring: codec: max-in-memory-size: 10MB ``` --- ### 三、异常触发 - 若请求体超过设定值,会抛出`DataBufferLimitException`,提示类似: ```java org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer ``` --- ### 四、注意事项 1. **权衡内存与性能** - 值过大 → 增加内存压力,影响稳定性 - 值过小 → 频繁磁盘写入,降低吞吐量 2. **WebFlux专属** 该属性仅对基于Reactor的响应式应用生效。传统Spring MVC需使用`spring.servlet.multipart.max-file-size`等属性。 3. **细粒度控制** 可通过自定义`ServerCodecConfigurer`对特定接口单独设置: ```java @Bean public WebFluxConfigurer webFluxConfigurer() { return new WebFluxConfigurer() { @Override public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) { configurer.defaultCodecs().maxInMemorySize(20 * 1024 * 1024); //20MB } }; } ``` --- ### 五、典型应用场景 - 上传超过默认限制的图片/视频 - 接收包含大型JSON数组的POST请求 - 微服务间传输大数据时调整网关配置 合理设置此参数可平衡系统资源利用率和请求处理能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值