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節點帶寬,給其他頻繁的小數據包請求讓路,這樣更理想。
