应将超长文本存入对象存储(如OSS/MinIO),RabbitMQ仅传递轻量引用;生产者需流式上传、生成唯一key或预签名URL,消息体仅含JSON元数据。

Java 中处理超长文本这类大对象消息,不能直接塞进 RabbitMQ。RabbitMQ 不是文件传输管道,它设计目标是低延迟、高吞吐的元数据通信。一旦消息体超过几 MB,就会迅速拖垮 JVM 堆、Erlang 节点内存和磁盘 I/O。真正可行的做法,是把大内容存到对象存储(OSS/MinIO),RabbitMQ 只传一个轻量引用。
生产者:上传文本到 OSS,只发 URL 或 key
不要用 Files.readAllBytes() 读全文再发 —— 这会让 10MB 文本在 Java 堆里复制多份。应流式上传,并构造最小化消息体:
- 用
ossClient.putObject(bucket, key, inputStream)或minioClient.putObject()直接上传文本流(如new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) - 生成唯一 key,例如
"text/20260720/abc123456789.json",或签发短期有效的 presigned URL - 消息体仅含 JSON 元数据:
{"key":"text/20260720/abc123456789.json","size":12458732,"encoding":"utf-8"}(通常 - 务必设置
messageProperties.setContentType("application/json")和deliveryMode = 2(持久化)
消费者:按需拉取,边读边处理
收到消息后,不反序列化整个文本内容,而是根据 key 或 URL 流式获取:
- 用
ossClient.getObject(bucket, key)返回S3Object,调用getObjectContent()获取InputStream - 用
BufferedReader或 Jackson Streaming API 逐行/逐段解析,避免全量加载 - 处理完立即关闭流,释放连接和缓冲区资源
- 若用 presigned URL,则用
HttpURLConnection或OkHttpClient发 GET 请求,同样流式读取
关键配置与安全边界
RabbitMQ 本身无需为大消息调参,反而要收紧限制防止误用:
立即学习“Java免费学习笔记(深入)”;
- 服务端强制设置
max_message_size = 16384(16KB),从源头拦截超长 payload - 消息加
x-message-ttl=3600,确保引用失效前任务能完成 - OSS 上配置生命周期规则,例如 7 天后自动清理未被消费的文本对象
- 消费端必须禁用
autoAck=true,只有文本下载成功 + 校验通过 + 业务逻辑完成,才调用channel.basicAck()
为什么不用 prefetch 或多线程加速?
这不是 CPU 或并发瓶颈,而是 I/O 和内存带宽受限:
-
prefetch > 1会导致多个大文本流同时打开,快速耗尽连接池和堆内存 - 开 10 个线程去“并发消费”,实际只是争抢同一块网卡和磁盘带宽,吞吐不增反降
- 推荐
prefetch = 1+concurrency = 1~2,配合流式处理,稳定压测吞吐可达 300+ MB/s(取决于 OSS 带宽)


















