概述
在上一篇文章《簡易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, 以便反序列化呼叫結果。如下所示:
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 的序列化器和反序列化器即可。