前言
在《dubbo架构篇》中可知Serialization层为dubbo的最底层。序列化说白了就是把内存中的对象转化成二进制,再由二进行转化为内存对象的过程。
序列化
dobbo提供Serialization接口
@SPI("hessian2")
public interface Serialization {
// 返回dubbo自定义的序列化ID
byte getContentTypeId();
// 返回序列化文本描述
String getContentType();
// 定义序列化方法
@Adaptive
ObjectOutput serialize(URL url, OutputStream output) throws IOException;
// 定义反序列化方法
@Adaptive
ObjectInput deserialize(URL url, InputStream input) throws IOException;
}
从《dubbo之SPI》分析得知生成 Serialization$Adaptive:
- 如果url存在serialization参数,则会在spi容器中找到对应的Serialization实体类
- 如果不存在,则用hessian2
public class SerializationTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 从根据Serialization规则生成Serialization$Adaptive
Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getAdaptiveExtension();
// 使用Adaptive规则使用protostuff序列化工具
URL url = URL.valueOf("http://127.0.0.1/?serialization=protostuff");
PP pp = new PP();
pp.setAge(15);
pp.setSex(2);
ByteArrayOutputStream output = new ByteArrayOutputStream();
serialization.serialize(url, output).writeObject(pp);
ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
PP p1 = serialization.deserialize(url, input).readObject(PP.class);
// 输出结果 age:15 sex:2
System.out.println(p1);
}
}
协议
查看org/apache/dubbo/dubbo/2.7.8/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization文件,dubbo支持各种序列化协议
fastjson=org.apache.dubbo.common.serialize.fastjson.FastJsonSerialization
fst=org.apache.dubbo.common.serialize.fst.FstSerialization
hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization
native-hessian=org.apache.dubbo.serialize.hessian.Hessian2Serialization
java=org.apache.dubbo.common.serialize.java.JavaSerialization
compactedjava=org.apache.dubbo.common.serialize.java.CompactedJavaSerialization
nativejava=org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization
kryo=org.apache.dubbo.common.serialize.kryo.KryoSerialization
kryo2=org.apache.dubbo.common.serialize.kryo.optimized.KryoSerialization2
avro=org.apache.dubbo.common.serialize.avro.AvroSerialization
protostuff=org.apache.dubbo.common.serialize.protostuff.ProtostuffSerialization
gson=org.apache.dubbo.common.serialize.gson.GsonSerialization
protobuf-json=org.apache.dubbo.common.serialize.protobuf.support.GenericProtobufJsonSerialization
protobuf=org.apache.dubbo.common.serialize.protobuf.support.GenericProtobufSerialization
序列化协议选用原则,通常应该从三方面考虑:
1. 序列化后的二进制序列大小。(IO少)
2. 序列化、反序列化的速率。(CPU少)
3. 兼容性
兼容性,比如说你要在XX接口返回值中加一个值,或者参数对象中加入一个值。如果在原接口上直接加会导致原有接口报错,强迫客户版本必须要升级。如果不升级要新加一方法。这是很不舒服的一件事情。
对常用序列化工具相关文章:
协议 | 说明 |
---|---|
hessian2 | dubbo默认《浅析Hessian协议》 |
protostuff | 《序列化工具-Protobuf》 |
就性能而言protostuff>hessian2
但兼容性方面:
- hessian2类似于json,可随意位置加字段。方便
- protostuff只能在类最后加字段。