You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux项目ByteBuf未释放内存泄漏问题求助

问题分析与解决方案

核心原因

从泄漏日志的调用栈可以看出,ByteBuf泄漏发生在r2dbc-mssql驱动的RpcEncoding类处理null值编码的逻辑中,属于驱动内部资源未正确释放的问题,同时Netty版本不兼容、异常处理不当会加剧这类问题的出现。

具体解决步骤

1. 修复Netty版本冲突

你的POM中手动指定了netty-resolver-dns-native-macos版本为4.1.110.Final,但Spring Boot 3.3.0默认管理的Netty版本是4.1.111.Final,版本不一致会导致Netty资源管理逻辑异常。

修改方式:
移除手动添加的该依赖,让Spring Boot父依赖自动管理版本:

<!-- 移除以下手动指定的依赖 -->
<!--
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-resolver-dns-native-macos</artifactId>
    <version>4.1.110.Final</version>
    <classifier>osx-aarch_64</classifier>
</dependency>
-->

如果确实需要原生DNS解析依赖,添加时不指定版本,继承Spring Boot的管理版本:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-resolver-dns-native-macos</artifactId>
    <classifier>osx-aarch_64</classifier>
</dependency>

2. 升级r2dbc-mssql驱动版本

r2dbc-mssql 1.3.x早期版本存在ByteBuf泄漏的已知问题,升级到修复后的版本即可解决。Spring Boot 3.3.0兼容的最新稳定版本为1.3.4,在POM中明确指定:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-mssql</artifactId>
    <version>1.3.4</version>
    <scope>runtime</scope>
    <exclusions>
        <exclusion>
            <groupId>io.projectreactor.netty</groupId>
            <artifactId>reactor-netty-http-brave</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3. 修正异常处理逻辑

当前代码中onErrorResume直接返回Mono.empty(),会吞掉所有异常,包括可能导致资源未释放的连接异常。正确做法是:

  • 不吞掉异常,返回明确的错误响应;
  • 确保异常发生时上游资源能被正确释放。

修改后的代码示例:

return myRepository.findItems(itemType, fromDate, toDate)
    .collectList()
    .switchIfEmpty(Mono.error(buildError(404, ITEM_NOT_FOUND)))
    .flatMapMany(Flux::fromIterable)
    .flatMap(this::aggregateItemsData)
    .map(itemBuilder::toItemData)
    .onErrorResume(throwable -> {
        log.error("getItems failed: {}", throwable.getMessage(), throwable); // 打印完整栈信息便于排查
        return Mono.error(buildError(500, "Internal Server Error")); // 返回标准错误响应
    });

4. 检查aggregateItemsData方法

该方法包含额外DB调用,需确保:

  • 所有Reactor流使用正确操作符,避免嵌套订阅(如block()/subscribe());
  • 使用using/usingWhen等操作符管理DB连接或资源的生命周期;
  • 不在方法中创建未被正确释放的资源。

验证方法

  1. 启动应用后,观察日志是否再出现ByteBuf泄漏提示;
  2. 对接口进行压测,检查是否还有连接关闭异常;
  3. 查阅r2dbc-mssql官方发布日志,确认升级版本已修复对应泄漏问题。

内容的提问来源于stack exchange,提问作者ElephantLove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:00:54