项目中使用了服务框架Dubbo进行远程调用,框架持久层使用的是Spring data jpa,一同事开发的Dubbo接口类似入如下:
XXXXService.findBy(PageRequest pg );其中PageRequest 是spring data jps提供的分页排序实现类。
当在客户端调用该接口时,PageRequest 中明明传入的油蚕丝,但一到Dubbo反序列化,Dubbo
总时抛 PageRequest could not be instantiated;跟了下Dubbo的源码,发现这个异常是在
JavaDeserializer(Dubbo序列化类)中抛出的,再看异常cause by,发现是 PageRequest的
父类AbstractPageRequest 构造函数检查失败出的问题,
public AbstractPageRequest(int page, int size) {
if (page < 0) {
throw new IllegalArgumentException("Page index must not be less than zero!");
}
if (size < 1) {
throw new IllegalArgumentException("Page size must not be less than one!");
}
this.page = page;
this.size = size;
}
就红的地方抛出类异常,也就是说size=0啦。很奇怪,明明出入的PageRequest有值,为啥Dubbo反序列就把变成零了,带着这个问题,有跟了一遍Dubbo源码,发现在JavaDeserializer
public JavaDeserializer(Class cl)
{
_type = cl;
_fieldMap = getFieldMap(cl);
_readResolve = getReadResolve(cl);
if (_readResolve != null) {
_readResolve.setAccessible(true);
}
Constructor []constructors = cl.getDeclaredConstructors();
long bestCost = Long.MAX_VALUE;
for (int i = 0; i < constructors.length; i++) {
Class []param = constructors[i].getParameterTypes();
long cost = 0;
for (int j = 0; j < param.length; j++) {
cost = 4 * cost;
if (Object.class.equals(param[j]))
cost += 1;
else if (String.class.equals(param[j]))
cost += 2;
else if (int.class.equals(param[j]))
cost += 3;
else if (long.class.equals(param[j]))
cost += 4;
else if (param[j].isPrimitive())
cost += 5;
else
cost += 6;
}
if (cost < 0 || cost > (1 << 48))
cost = 1 << 48;
cost += (long) param.length << 48;
if (cost < bestCost) {
_constructor = constructors[i];
bestCost = cost;
}
}
if (_constructor != null) {
_constructor.setAccessible(true);
Class []params = _constructor.getParameterTypes();
_constructorArgs = new Object[params.length];
for (int i = 0; i < params.length; i++) {
_constructorArgs[i] = getParamArg(params[i]);
}
}
}
有对_constructor和 _constructorArgs初始化的过程,大致意思是会调用所有构造函数中参数最少的那个。
也就是会调用PageRequest中
public PageRequest(int page, int size) {
this(page, size, null);
}
再跟到上面标红的地方,也就是_constructorArgs初始化代码
protected static Object getParamArg(Class cl)
{
if (! cl.isPrimitive())
return null;
else if (boolean.class.equals(cl))
return Boolean.FALSE;
else if (byte.class.equals(cl))
return new Byte((byte) 0);
else if (short.class.equals(cl))
return new Short((short) 0);
else if (char.class.equals(cl))
return new Character((char) 0);
else if (int.class.equals(cl))
return Integer.valueOf(0);
else if (long.class.equals(cl))
return Long.valueOf(0);
else if (float.class.equals(cl))
return Float.valueOf(0);
else if (double.class.equals(cl))
return Double.valueOf(0);
else
throw new UnsupportedOperationException();
}
上面方法加红的部分,答案揭晓,dubbo全返回0了,所有才有了前面的错误Page size must not be less than one!
总结,Dubbo默认使用的是Hessian序列化,具体可以看下Hessian这个序列化框架,若使用Hessian,默认情况下最好都提供一个无参构造函数
分享到:
相关推荐
- 在实际开发中,我们可能会需要编写一些辅助工具类来处理Hessian的相关操作,例如Hessian2Input和Hessian2Output,它们用于读写Hessian序列化的二进制流。 6. **安全性与优化**: - 虽然Hessian协议效率高,但其...
在Dubbo中,Hessian协议同样可以被用于服务的远程调用,它提供了比RMI更快的序列化和反序列化速度,特别适合于需要高效率通信的场景。 要使用Dubbo与RMI或Hessian集成,我们需要进行以下步骤: 1. **配置服务提供...
在Dubbo中,Hessian Lite被用作服务调用的序列化/反序列化工具,使得服务间通信更加高效和便捷。 描述中提到的 "可以使用mvn install命令将jar包安装到本地的maven仓库" 是一个常见的Maven操作。Maven是一个项目...
Dubbo 提供了多种序列化方式,其中之一就是 Hessian 序列化,而 hessian-lite 是 Dubbo 在编译时依赖的一个轻量级 Hessian 实现。在实际开发过程中,可能会遇到由于阿里的网络限制导致无法直接获取 hessian-lite 这...
默认就是⾛ dubbo 协议,单⼀⻓连接,进⾏的是 NIO 异步通信,基于 hessian 作为序列化协议。使⽤的场景是:传输数据量⼩ (每次请求在 100kb 以内),但是并发量很⾼。 为了要⽀持⾼并发场景,⼀般是服务提供者就⼏...
a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...
" 暗示了我们即将探讨的是关于Dubbo框架在网络通信和数据序列化方面的内容。Dubbo是阿里巴巴开源的一个高性能、轻量级的Java服务治理框架,它为分布式应用提供了服务调用、注册与发现、监控等能力。在实现远程服务...
- **Dubbo协议**:默认协议,采用单个长连接和NIO异步通信,基于Hessian进行序列化。适用于大数据量但并发量高的场景。 - **RMI协议**:基于Java原生序列化,多短连接,适合消费者和提供者数量相近的情况,常用于...
描述进一步提到,“nodejs 使用原生的 dubbo (dubbo head hessian body) 协议”,这表明在Node.js中,开发者不仅实现了Dubbo的协议头(head),还处理了Hessian二进制序列化协议作为消息体(body)。Hessian是一种...
Hessian-lite,作为一款轻量级的二进制序列化框架,被广泛应用于分布式服务框架Dubbo中,为远程调用提供高效的数据传输支持。本文将深入探讨Hessian-lite的核心概念、功能特性以及它在Dubbo中的具体应用。 一、...
Dubbo 的序列化框架默认使用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列化等其他选择。 Hessian 序列化是一个采用二进制格式传输的服务框架,相对传统 soap web service,更轻量,更快速。 Dubbo 的...
接口定义了数据的序列化与反序列化,Dubbo内置了多种序列化方式,如Java、FastJson、Hessian等。选择合适的序列化方式对性能有显著影响。 五、服务治理 5.1 监控中心(Monitor) Dubbo提供了监控中心,可以收集...
【Dubbo推荐使用什么序列化框架?】 推荐使用Hessian,还有Duddo、FastJson、Java自带的序列化框架可供选择。 【Dubbo默认使用什么通信框架,还有其他选择吗?】 默认使用Netty,也支持Mina和Grizzly。 【Dubbo...
在DEMO中,我们通常使用默认的Dubbo协议和Hessian序列化。 5. **配置中心(Config Center)** 配置中心可以集中管理服务的元数据,如服务版本、路由规则、权重等。虽然这不是DEMO的必要部分,但了解这一概念有助于...
1. **序列化**:Dubbo 默认使用 Hessian 2 序列化库,同时支持 Java 的 Serializable 机制,并提供了更高效的序列化实现。 - **Hessian 2**:一种高效的二进制格式,适合网络传输。 - **Java Serializable**:Java...
- **在Dubbo中的作用**:作为Dubbo的序列化协议之一,Hessian-lite可以用于Dubbo服务间的通信,提高数据交换的效率。 3. **Opensesame**: - **简介**:Opensesame是阿里巴巴内部的一个权限控制框架,用于实现细...
- **序列化**:包括Java自带的序列化、Hessian、FastJson等多种序列化方式,提高数据传输效率。 - **异步调用**:支持异步调用模式,提高了系统的响应速度和并发处理能力。 3. **性能优化**: - **高性能NIO**:...
8. **协议与序列化**:Dubbo支持的通信协议(如Dubbo、RMI、Hessian、HTTP等)和序列化方式(如Java自带序列化、Hessian2、Fastjson等),及其性能比较。 9. **Spring整合**:如何将Dubbo与Spring框架集成,利用...
序列化是远程调用中必不可少的一环,Dubbo支持多种序列化方式,如Java自带的序列化、Hessian2、FastJson等。选择合适的序列化方式可以影响到系统的性能和兼容性。 8. **容错机制** Dubbo提供了多种容错策略,如...