Dubbo 序列化
1、什么是序列化和反序列化
序列化(serialization)在计算机科学的资料处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)。
2、Dubbo 序列化
Dubbo 设计序列化的时候,设计了一个接口Serialization,接口下有具体的序列化实现方案。
1、JDK 的序列化方式
2、Hessian2 Hessian 序列化方式第二个版本, Dubbo 自己的序列化方式,Dubbo 默认方案
3、基于 Json 的序列化方式。目前有两种方案,一种是采用阿里的 FastJson 库,另外一种是采用 dubbo 中自己实现的简单 json 库,使用这种序列化方式,基本上使用的都是http协议。
4、Kryo Java 序列化方式,后续替换 Hessian2 一种非常成熟的序列化实现。相对比较新
5、FST Java序列化方式,后续替换 Hessian2 会中非常成熟的序列化方案。相对比较新
6、跨语言序列化方式:ProtoBuf (性能最优),Thrift ,Avro (大数据),(MsgPackage是一种有效的二进制格式,允许在多种语言(如Json)交换数据,但他体积更小。短整形被编码成为一个字节)。
3、FastJson2 序列化方式
1、引入依赖
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.23</version>
</dependency>
2、XML 的配置方式
<dubbo:protocol name="dubbo" port="-1" serialization="fastjson2"/>
3、SpringBoot 的配置方式
dubbo:
protocol:
name: dubbo
port: -1
serialization: fastjson2
4、Consumer 端
<dubbo:reference interface="com.suns.service.UserService" id="userService" url="dubbo://192.168.50.62:20880/com.suns.service.Use
rService?serialization=fastjson2"/>
4、 实现原理
通过源码的方式分析它们的实现原理。下面我们直接到序列化的核心类org.apache.dubbo.remoting.transport.CodecSupport
我们看其中的反序列化方法deserialize
:
public static ObjectInput deserialize(URL url, InputStream is, byte proto) throws IOException {
//获取序列化对象
Serialization s = getSerialization(url, proto);
return s.deserialize(url, is);
}
getSerialization
方法:
public static Serialization getSerialization(URL url, Byte id) throws IOException {
//通过协议查找Serialization对象
Serialization serialization = getSerializationById(id);
String serializationName = url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION);
//...
return serialization;
}
上面查找通过 SPI 注册的所有序列化方式。我们接着deserialize
方法看,这里我们以 Java JDK 提供的序列化方式为例:
public ObjectInput deserialize(URL url, InputStream is) throws IOException {
return new JavaObjectInput(is);
}
可以看到通过 JDK 提供的 JavaObjectInput
对象包装数据流。 其他的序列化方式也是类似