摘要:由于我们还未谈到具体的调用机制,因此暂且认为就是把一个包含了调用信息的对象,从经过序列化,变成一串二进制流,发送到了端。
概述
在上一篇文章《简易RPC框架:基于 netty 的协议编解码》中谈到对于协议的 decode 和 encode,在谈 decode 之前,必须先要知道 encode 的过程是什么,它把什么东西转化成了二进制协议。
由于我们还未谈到具体的 RPC 调用机制,因此暂且认为 encode 就是把一个包含了调用信息的 Java 对象,从 client 经过序列化,变成一串二进制流,发送到了 server 端。
这里需要明确的是,encode 的职责是拼协议,它不负责序列化,同样,decode 只是把整个二进制报文分割,哪部分是报文头,哪部分是报文体,诚然,报文体就是被序列化成二进制流的一个 Java 对象。
对于调用方来说,先将调用信息封装成一个 Java 对象,经过序列化后形成二进制流,再经过 encode 阶段,拼接成一个完整的遵守我们定好的协议的报文。
对于被调用方来说,则是收取完整的报文,在 decode 阶段将报文中的报文头,报文体分割出来,在序列化阶段将报文体反序列化为一个 Java 对象,从而获得调用信息。
本文探讨序列化机制。
由于这个 RPC 框架基于 netty 实现,因此序列化机制其实体现在了 netty 的 pipeline 上的 handler 上。
例如对于调用方,它需要在 pipeline 上加上一个 序列化 encode handler,用来序列化发出去的请求,同时需要加上一个反序列化的 decode handler, 以便反序列化调用结果。如下所示:
protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtocolEncoder()) .addLast(new ProtocolDecoder()) .addLast(new SerializationHandler(serialization)) .addLast(new DeserializationHandler(serialization)); }
其中的 SerializationHandler 和 DeserializationHandler 就是上文提到的序列化 encode handler 和反序列化 decode handler。
同样,对于被调用方来说,它也需要这两个handler,与调用方的 handler 编排顺序一致。
其中,serialization 这个参数的对象代表具体的序列化机制策略。
序列化机制上文中,SerializationHandler 和 DeserializationHandler 这两个对象都需要一个 serialization 对象作为参数,它是这么定义的:
private ISerialization serialization = SerializationFactory.getSerialization(ServerDefaults.DEFAULT_SERIALIZATION_TYPE);
采用工厂模式来创建具体的序列化机制:
/** * 序列化工厂 * * @author beanlam * @version 1.0 */ public class SerializationFactory { private SerializationFactory() { } public static ISerialization getSerialization(SerializationType type) { if (type == SerializationType.JDK) { return new JdkSerialization(); } return new HessianSerialization(); } }
这里暂时只支持 JDK 原生序列化 和 基于 Hessian 的序列化机制,日后若有其他效率更高更适合的序列化机制,则可以在工厂类中进行添加。
这里的 hessian 序列化是从 dubbo 中剥离出来的一块代码,感兴趣可以从 dubbo 的源码中的 com.caucho.hessian 包中获得。
以 HessianSerialization 为例:
/** * @author beanlam * @version 1.0 */ public class HessianSerialization implements ISerialization { private ISerializer serializer = new HessianSerializer(); private IDeserializer deserializer = new HessianDeserializer(); @Override public ISerializer getSerializer() { return serializer; } @Override public IDeserializer getDeserializer() { return deserializer; } @Override public boolean accept(Class> clazz) { return Serializable.class.isAssignableFrom(clazz); } }
根据 Hessian 的 API, 分别返回一个 hessian 的序列化器和反序列化器即可。
**
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72106.html
摘要:报文类型对于框架来说,报文可能有多种类型心跳类型报文认证类型报文请求类型报文响应类型报文等。接口调用请求的发送,在多条连接之间进行负载均衡。 1 需求分析 RPC 全称 Remote Procedure Call ,简单地来说,它能让使用者像调用本地方法一样,调用远程的接口,而不需要关注底层的具体细节。 例如车辆违章代办功能,如果车辆因为某种原因违章,只需要通过这个违章代办功能(它也许...
摘要:概述在简易框架需求与设计这篇文章中已经给出了协议的具体细节,协议类型为二进制协议,如下协议的解码我们称为,编码我们成为,下文我们将直接使用和术语。直接贴代码,参考前文提到的协议格式阅读以下代码协议编码器 概述 在《简易RPC框架:需求与设计》这篇文章中已经给出了协议的具体细节,协议类型为二进制协议,如下: ---------------------------------------...
摘要:对于与而言,则可以看做是消息传递技术的一种衍生或封装。在生产者通知消费者时,传递的往往是消息或事件,而非生产者自身。通过消息路由,我们可以配置路由规则指定消息传递的路径,以及指定具体的消费者消费对应的生产者。采用和来进行远程对象的通讯。 消息模式 归根结底,企业应用系统就是对数据的处理,而对于一个拥有多个子系统的企业应用系统而言,它的基础支撑无疑就是对消息的处理。与对象不同,消息本质上...
摘要:微软的虽然引入了事件机制,可以在队列收到消息时触发事件,通知订阅者。由微软作为主要贡献者的,则对以及做了进一层包装,并能够很好地实现这一模式。 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基...
摘要:微软的虽然引入了事件机制,可以在队列收到消息时触发事件,通知订阅者。由微软作为主要贡献者的,则对以及做了进一层包装,并能够很好地实现这一模式。 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基...
阅读 2013·2021-11-15 11:38
阅读 2047·2019-08-30 15:55
阅读 2181·2019-08-30 15:52
阅读 3166·2019-08-30 14:01
阅读 2683·2019-08-30 12:47
阅读 1127·2019-08-29 13:17
阅读 1060·2019-08-26 13:55
阅读 2628·2019-08-26 13:46