Resteasy-Reactive-Client处理Multipart请求时Attr_临时文件未自动删除
我在使用Reactive Client执行Multipart HTTP请求时,遇到了临时文件无法删除的问题。
我有一个运行在服务器上的原生Quarkus应用("sender"),通过Multipart请求向另一个Quarkus应用("collector")的REST端点发送文件。
Rest Client定义
@RegisterRestClient(configKey = "collector-client") @Path("/api/v1") public interface CollectorRestClient { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) @Path("/message/") String sendMessageFile(CollectorDto collectorDto); }
DTO定义
public class CollectorDto { @FormParam("file") @PartType(MediaType.APPLICATION_OCTET_STREAM) private File file; @FormParam("messageId") @PartType(MediaType.TEXT_PLAIN) private String messageId; @FormParam("providerId") @PartType(MediaType.TEXT_PLAIN) private String providerId; @FormParam("receivedDateTime") @PartType(MediaType.TEXT_PLAIN) private Instant receivedDateTime; ... }
运行一段时间后,sender所在的宿主系统出现文件写入问题,调查发现文件系统的inode已耗尽,生成了约600万个名为Attr_7976485966177727808_571797615这类的小体积临时文件。
看起来Multipart请求的每个部分都会生成对应的Attr_文件,文件内容为该部分的值。
经过研究,我发现Netty的DefaultHttpDataFactory类的createAttribute方法是创建这些DiskAttribute实例的地方。
Quarkus的默认配置似乎启用了useDisk模式并持久化Multipart属性,同时由于DefaultHttpDataFactory的默认值,属性的deleteOnExit标志被设为false。
补充说明:Netty在2020年3月的提交中将deleteOnExit默认值设为false,2020年9月的提交修复了相关泄漏问题,因此我不确定是否仍需保持默认值为false。
Netty建议在请求完成后手动释放HttpData:
for (InterfaceHttpData httpData: decoder.getBodyHttpDatas()) { httpData.release(); factory.removeHttpDataFromClean(request, httpData); } factory.cleanAllHttpData(); decoder.destroy();
但我仅调用带有@RegisterRestClient注解的接口的@Post方法,不知道如何获取Decoder和Factory的访问权限。
期望行为:
在HTTP请求完成后(例如响应已反序列化),应删除所有在请求上下文创建的临时文件。
当前行为:
Multipart请求的属性被持久化为临时文件,且不会自动清理;由于无法访问HttpDataFactory和Decoder,手动清理也无法实现。
遇到的问题:
- 试图通过配置来设置Netty的
useDisk和deleteOnExit行为,但未找到合适的配置属性。 - 尝试手动触发DiskAttributes的清理,但无法轻松获取持有所需数据的Netty对象实例。
使用的版本:
| lib | 版本 |
|---|---|
| quarkus | 2.16.6-Final |
| resteasy-reactive-client | 2.16.6-Final |
| netty | 4.1.86.Final |
内容的提问来源于stack exchange,提问作者fantasticExecution

