简易RPC框架:序列化机制

概述

在上一篇文章《简易RPC框架:基于 netty 的协议编解码》中谈到对于协议的 decode 和 encode,在谈 decode 之前,必须先要知道 encode 的过程是什么,它把什么东西转化成了二进制协议。
由于我们还未谈到具体的 RPC 调用机制,因此暂且认为 encode 就是把一个包含了调用信息的 Java 对象,从 client 经过序列化,变成一串二进制流,发送到了 server 端。
这里需要明确的是,encode 的职责是拼协议,它不负责序列化,同样,decode 只是把整个二进制报文分割,哪部分是报文头,哪部分是报文体,诚然,报文体就是被序列化成二进制流的一个 Java 对象。
对于调用方来说,先将调用信息封装成一个 Java 对象,经过序列化后形成二进制流,再经过 encode 阶段,拼接成一个完整的遵守我们定好的协议的报文。
对于被调用方来说,则是收取完整的报文,在 decode 阶段将报文中的报文头,报文体分割出来,在序列化阶段将报文体反序列化为一个 Java 对象,从而获得调用信息。
本文探讨序列化机制。

基于 netty handler

由于这个 RPC 框架基于 netty 实现,因此序列化机制其实体现在了 netty 的 pipeline 上的 handler 上。
例如对于调用方,它需要在 pipeline 上加上一个 序列化 encode handler,用来序列化发出去的请求,同时需要加上一个反序列化的 decode handler, 以便反序列化调用结果。如下所示:

1
2
3
4
5
6
7
8
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 对象作为参数,它是这么定义的:

1
private ISerialization serialization = SerializationFactory.getSerialization(ServerDefaults.DEFAULT_SERIALIZATION_TYPE);

采用工厂模式来创建具体的序列化机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 序列化工厂
*
* @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 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* @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 的序列化器和反序列化器即可。

beanlam wechat
欢迎订阅我的个人公众号
壕无人性