Dubbo Data length too large: 11557050, max payload: 8388608 传输数据超限
com.alibaba.dubbo.remoting.transport.AbstractCodec.checkPayload() ERROR Data length too large: 11557050, max payload: 8388608 java.io.IOException: Data length too large: 11557050, max payload: 838860
故障缘由:
最近做一个功能,前端Spring MVC做Excel文件导入,前端仅负责接收上传数据,解析需交由后端Dubbo Provider解析并持久化到数据库,前端接收文件流,由于Dubbo无法直接对文件流进行传输,随将文件流转byte(能序列化)走Dubbo底层协议传输。
起初小文件传输没有问题,但是文件超过8M后,出现本文顶端的异常,由Provider抛出,不难看出,Dubbo对传输的数据包做了8M限制,超限即抛异常,尽管这个问题阿里和当当的Dubbox已经放开了这个限制,详见(https://code.aliyun.com/alibaba/dubbo/commit/827769f8ad1e05f5b7caf0f09afe2aec344096cd https://github.com/dangdangdotcom/dubbox/pull/33/files?diff=split),但是仔细想想,这并不符合Dubbo设计的初衷,Dubbo的长连接并不是为这种大数据包传输服务的,主要用于小数据包频繁调用,所以这个场景的设计就是有问题的。
如何解决?
1、如果不想修改代码及其他结构,那没办法,要么升级Dubbo版本(这明显动作很大,有很多风险)
2、将Excel文件内容拆成小于8M的N个文件
3、大于8M的Excel文件前端接收后将文件流转换后的Byte做切割,切成小于8M然后挨个传输,但是Consumer和Provider必须保证头尾完整,Provider才能完整解析
4、Excel大文件由Consumer接收后上传至指定FTP服务器,Provider从FTP服务器取回解析,这里也可用其他分布式文件服务器,或者放到Mongodb或Redis库,看自己设计。
5、看项目架构及结构,直接由Consumer解析,但有些场景并不允许。
建议:
个人倾向于上述建议第4条,本来就是分布式架构,跳过RPC传输大数据包,直接从第三方服务器取,这样减轻了Dubbo的压力,也不会占用某个连接对应的Provider节点带宽,给其他频繁的小数据包请求让路,这样更理想。