[BUG] - Java-Chassis 新版本无法自动清理临时上传文件的句柄
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Bắt đầu với foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/FileUploadPart.java và xem xét thay đổi liên quan đến issue #4476. Tái hiện hành vi giữ handle trên Linux bằng Java-Chassis 2.8.24, sau đó xác định và kiểm chứng một thiết kế dọn dẹp vẫn tương thích với Java 8 và Java 21 mà không làm gián đoạn quá trình xử lý upload không đồng bộ.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Steps to Reproduce
- 编写一个处理文件上传请求的controller.
- 接收到上传文件参数后, 打开文件流, 不关闭, 直接返回.
- 在Java-Chassis 1.x分支上可以观察到一段时间后文件句柄会被清理, 而在 Java-Chassis 2.8.24 版本, 文件句柄会一直存在, 直到进程重启才会消失.
注意:
- 实际测试发现此问题在Windows上不会出现(Java8), 我们是在Linux上复现的问题.
- 打开文件流不关闭只是为了让问题必现. 实际上即使业务代码有正常的close调用也可能遇到类似的问题, 因为业务处理文件流的逻辑可能超时, 导致 Vert.x 执行临时文件清理回调时文件流仍然处于打开的状态.
Expected Behavior
预期 Java-Chassis 2.8.24 能像 Java-Chassis 1.x 分支一样, 能够自动兜底清理文件句柄.
Servicecomb Version
2.8.24
Additional Context
根因分析
导致 Java-Chassis 1.x 和 2.8.x 差异的代码在于:
在更早的版本中, 它返回的是一个 FileInputStream:
而 2.8.20 版本对此做了上述修改, 实测返回的是 sun.nio.ch.ChannelInputStream 类型的流.
在 Java8 中, FileInputStream 的 finalize 方法会执行 close 方法, 而 sun.nio.ch.ChannelInputStream 的 finalize 方法是空的. 这就导致 Java-Chassis 2.8.19 及之前的版本, 即使业务代码由于各种各样的原因没有执行 close 方法, FileInputStream 也能在被GC回收时兜底关闭文件句柄, 而在升级到 Java-Chassis 2.8.20 之后就只能泄漏句柄了.
回溯 Java-Chassis 的代码修改记录可知, 这个变化是为了修复另外一个问题而引入的:
https://github.com/apache/servicecomb-java-chassis/issues/4476
解决思路
Java-Chassis 已经不适合将文件输入流的类型改回 FileInputStream 了.
除了上面说的 issue #4476 的原因, 高版本的 Java 还废弃了 finalize 方法, 即使用回 FileInputStream 也不能兜底关闭文件句柄.
为了能够同时兼容 Java8 和 Java21, 也不适合选用 Cleaner 机制(Java9才具备此特性).
目前能想到的解决办法:
-
基于 Java-Chassis 自身的 Invocation 生命周期管理机制来做自动清理动作.
此方案的风险在于, 考虑到业务可能在 controller 层获取上传文件参数后, 异步调度到其他任务线程池处理, 因此在 Invocation 的结束事件发生时就直接关闭流的话可能会导致业务视角看到的Java-Chassis框架行为发生了影响业务功能的不兼容变化.
-
记录已打开的 InputStream, 在后台定时任务中监控其关闭状态.
此方案可以一定程度规避方案1的风险, 但存在内存用量上升甚至泄漏的风险, 若选择这个思路, 也需要小心进行可靠性设计.
此外, 建议Java-Chassis增加对 FileUploadPart 的打开流的调用记录的监控, 便于辅助业务分析此类文件句柄泄漏问题的触发代码位置.
- Ngôn ngữ chính
- Java
- Star
- 1.9k
- Fork
- 813
- Merge trung bình
- 8 ngày 23 giờ
- Pull request đã merge (30 ngày)
- 1
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/servicecomb-java-chassis
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
apache/servicecomb-java-chassis#5106 ·
-
question
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
apache/servicecomb-java-chassis#5153 · 1 bình luận ·
-
[QUESTION] - 请发布3.x的最新版本 Đang mởquestion
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
apache/servicecomb-java-chassis#5146 ·
-
[FEATURE] - When will ServiceComb support Spring Boot 4.x, Spring Framework 7.x, and Jackson 3.x? Đang mởenhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
apache/servicecomb-java-chassis#5145 ·
-
2.x bug
apache/servicecomb-java-chassis#5141 · 1 người được giao ·
Tất cả issue của apache/servicecomb-java-chassis
Issue tương tự
-
executions.Query — startDate and timeRange filters are sent with inverted comparison operators Đang mởarea/plugin
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
kestra-io/plugin-kestra#190 ·
-
litertlm-android AAR ships no consumer ProGuard rules → "mid == null" SIGABRT in minified apps Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
google-ai-edge/LiteRT-LM#3739 ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Add canonical URLs and a sitemap Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
integra-team-red/meet-map#249 ·
-
[Studio][Bug] Cancelled create-user dialog keeps the password and admin switch for the next attempt Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
apache/rocketmq-dashboard#5064 ·