dubbo icon indicating copy to clipboard operation
dubbo copied to clipboard

Dubbo client can not supported string message problem still happend

Open zyxdSTU opened this issue 3 years ago • 9 comments

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Environment

  • Dubbo version: 3.0.1
  • Operating System version: centos
  • Java version: 1.8

Steps to reproduce this issue

  1. setting provider payload <dubbo:provider id="payload" payload="104857600" filter="metrics"/>
  2. consumer invoke provider serivce, the response data size is 20M < 100M
  3. but consumer happend below problem,

url: dubbo://10.11.33.60:20881/org.apache.dubbo.metadata.MetadataService?codec=dubbo&dubbo=2.0.2&group=datacenter-api-local-asda&heartbeat=60000&port=20881&protocol=dubbo&release=3.0.1&side=consumer&timeout=5000&version=1.0.0, dubbo version: 3.0.1, current host: 10.11.33.60 java.lang.Exception: Dubbo client can not supported string message: 464642],[119.36135700386,42.0039224874151],[119.360002451097,42.003717625058],[119.359396533585,42.0035696501204],[119.358987376968,42.0031680333027],[119.358539561078,42.0026358628986],[119.358315878313,42.0022015564206],[119.358068629836,42.0008188241229],[119.357815799583,41.9995622580692]....

What do you expect from the above steps?

consumer can normal invoke the provider service

What actually happens?

in channel: NettyChannel [channel=[id: 0xef9fcee5, L:/10.11.33.60:63944 - R:/10.11.33.60:20881]], url: dubbo://10.11.33.60:20881/org.apache.dubbo.metadata.MetadataService?codec=dubbo&dubbo=2.0.2&group=datacenter-api-local-asda&heartbeat=60000&port=20881&protocol=dubbo&release=3.0.1&side=consumer&timeout=5000&version=1.0.0
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:184)
	at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)
	at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
	at java.lang.Thread.run(Thread.java:750)

zyxdSTU avatar Jul 04 '22 02:07 zyxdSTU

能再具体说下出现的场景吗,看起来是直接telnet了端口,然后写数据,不是通过服务端回传的

AlbumenJ avatar Jul 04 '22 06:07 AlbumenJ

能再具体说下出现的场景吗,看起来是直接telnet了端口,然后写数据,不是通过服务端回传的

1、provider提供一个数据查询服务 <T> RpcResult<CompQueryResult<T>> executeQuerySQL(String dataSourceKey, String sql, Class<T> clazz, Boolean returnHeader, 返回的数据大小可能大于8M 所以在Dubbo配置文件中,设置了payload为100M, <dubbo:provider id="payload" payload="104857600" filter="metrics"/>、 2、consumer在调用provider服务的时候,接收的数据大小超过8M后,抛出异常 NettyChannel [channel=[id: 0x4b4524e3, L:/10.11.33.60:49760 - R:/10.11.33.60:20881]], url: dubbo://10.11.33.60:20881/org.apache.dubbo.metadata.MetadataService?codec=dubbo&dubbo=2.0.2&group=datacenter-api-local-asda&heartbeat=60000&port=20881&protocol=dubbo&release=3.0.1&side=consumer&timeout=5000&version=1.0.0 at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:184) at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41) at java.lang.Thread.run(Thread.java:750) 能帮忙看一下吗? 卡了很久了。

zyxdSTU avatar Jul 04 '22 06:07 zyxdSTU

@AlbumenJ 我怀疑服务端回传的数据,被客户端截断了,导致不能正确处理,client端相关代码,和报出来的错误。

    @Override
    public void received(Channel channel, Object message) throws RemotingException {
        final ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
        if (message instanceof Request) {
            // handle request.
            Request request = (Request) message;
            if (request.isEvent()) {
                handlerEvent(channel, request);
            } else {
                if (request.isTwoWay()) {
                    handleRequest(exchangeChannel, request);
                } else {
                    handler.received(exchangeChannel, request.getData());
                }
            }
        } else if (message instanceof Response) {
            handleResponse(channel, (Response) message);
        } else if (message instanceof String) {
            if (isClientSide(channel)) {
                Exception e = new Exception("Dubbo client can not supported string message: " + message + " in channel: " + channel + ", url: " + channel.getUrl());
                logger.error(e.getMessage(), e);
            } else {
                String echo = handler.telnet(channel, (String) message);
                if (echo != null && echo.length() > 0) {
                    channel.send(echo);
                }
            }
        } else {
            handler.received(exchangeChannel, message);
        }
    }

报出来的错误,返回的经纬度信息只有一部分

java.lang.Exception: Dubbo client can not supported string message: 464642],[119.36135700386,42.0039224874151],[119.360002451097,42.003717625058],[119.359396533585,42.0035696501204],[119.358987376968,42.0031680333027],[119.358539561078,42.0026358628986],[119.358315878313,42.0022015564206],[119.358068629836,42.0008188241229],[119.357815799583,41.9995622580692]....

zyxdSTU avatar Jul 04 '22 06:07 zyxdSTU

请求的接口描述可以发一下吗,返回的格式是 String ?

AlbumenJ avatar Jul 04 '22 06:07 AlbumenJ

功能的话,主要是请求数据库表中的多行数据。

<T> RpcResult<CompQueryResult<T>> executeQuerySQL(String dataSourceKey, String sql, Class<T> clazz, Boolean returnHeader);

zyxdSTU avatar Jul 04 '22 06:07 zyxdSTU

这么大的payload为啥要通过rpc方式?会不会是序列化时间过长的原因?或者上传一个简单demo我们复现一下?

cheese8 avatar Jul 04 '22 08:07 cheese8

这么大的payload为啥要通过rpc方式?会不会是序列化时间过长的原因?或者上传一个简单demo我们复现一下?

demo有点难,我又找到了点蛛丝马迹,payload失效了? 为什么是MetaDataService, 而不是GPDataService(provider提供的服务)

ERROR org.apache.dubbo.remoting.exchange.codec.ExchangeCodec - [DUBBO] Data length too large: 11361246, max payload: 8388608, channel: NettyChannel [channel=[id: 0x7f457c68, L:/10.11.33.60:50972 - R:/10.11.33.60:20881]], dubbo version: 3.0.1, current host: 10.11.33.60 72408 [DubboClientHandler-thread-233] ERROR org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler - [DUBBO] Dubbo client can not supported string message: ?C0-org.zjvis.datacenter.service.vo.api.RpcResult?resulttraceIdtipsmessagecode isSuccess`tcom.alibaba.fastjson.JSONArrayMjava.util.LinkedHashMapAREADBZWn
url: dubbo://10.11.33.60:20881/org.apache.dubbo.metadata.MetadataService?codec=dubbo&dubbo=2.0.2&group=datacenter-api-local-asda&heartbeat=60000&port=20881&protocol=dubbo&release=3.0.1&side=consumer&timeout=5000&version=1.0.0, dubbo version: 3.0.1, current host: 10.11.33.60

zyxdSTU avatar Jul 04 '22 11:07 zyxdSTU

我这边本地没有复现出问题,出现是 org.apache.dubbo.metadata.MetadataService 的原因是取的 channel 的 url,这个默认只存第一个发布的 url,由于 org.apache.dubbo.metadata.MetadataService 是第一个发布的服务,所以日志写的是这个。 方便把客户端和服务端分机器部署看下吗,看下这个日志报错是在哪一侧抛出来的,是服务端抛的异常只是在消费端打印还是本身就是消费端异常。

AlbumenJ avatar Jul 04 '22 12:07 AlbumenJ

我这边本地没有复现出问题,出现是 org.apache.dubbo.metadata.MetadataService 的原因是取的 channel 的 url,这个默认只存第一个发布的 url,由于 org.apache.dubbo.metadata.MetadataService 是第一个发布的服务,所以日志写的是这个。 方便把客户端和服务端分机器部署看下吗,看下这个日志报错是在哪一侧抛出来的,是服务端抛的异常只是在消费端打印还是本身就是消费端异常。

我肯定消费端异常

zyxdSTU avatar Jul 04 '22 12:07 zyxdSTU

org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler - [DUBBO] Dubbo client can not supported string message: ?C0-org.zjvis.datacenter.service.vo.api.RpcResult?�result�traceId�tips�message�code isSuccess`t�com.alibaba.fastjson.JSONArrayM�java.util.LinkedHashMap�AREADBZWn url: dubbo://10.11.33.60:20881/org.apache.dubbo.metadata.MetadataService?codec=dubbo&dubbo=2.0.2&group=datacenter-api-local-asda&heartbeat=60000&port=20881&protocol=dubbo&release=3.0.1&side=consumer&timeout=5000&version=1.0.0, dubbo version: 3.0.1, current host: 10.11.33.60

org.zjvis.datacenter.service.vo.api.RpcResult

Seems like you have one customized data type here that might have affected the normal Dubbo RPC workflow.

chickenlj avatar Sep 02 '22 03:09 chickenlj

遇到了同样的问题,服务方向消费者提供一个超过8m的json字符串时就会触发同样的问题

LiXuD avatar Mar 30 '23 13:03 LiXuD

遇到了同样的问题,服务方向消费者提供一个超过8m的json字符串时就会触发同样的问题

set dubbo.protocol.payload

AlbumenJ avatar Mar 31 '23 07:03 AlbumenJ

是的,这样只能解决客户端向服务端发送超大对象的方式,但是服务端向客户端发送超大对象的时候,客户端并没有同步服务端的这个dubbo.protocol.payload设置,而是用了默认的8M(2.5.3版本直连模式下) 解决方案就是在url中手动添加payload参数

LiXuD avatar Apr 03 '23 08:04 LiXuD