rpc/fst序列化


title: Dubbo源码分析 - FST序列化
categories: RPC
tags:

  • Dubbo
    comments: false
    toc: true
    abbrlink: cfaae53
    date: 2020-05-05

概述

序列化总览 中介绍了 Dubbo 序列化抽象API相关接口,本篇文章将介绍 Dubbo 的 FST 序列化实现。

相关的代码结构如下图所示:

FST 工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class FstFactory {

/**
* 单例
*/
private static final FstFactory factory = new FstFactory();

/**
* FST 配置对象
*/
private final FSTConfiguration conf = FSTConfiguration.createDefaultConfiguration();


/**
* 静态方法,获取FST默认工厂
*
* @return
*/
public static FstFactory getDefaultFactory() {
return factory;
}

public FstFactory() {
// 将要序列化优化的类 注册到 FSTConfiguration 配置对象中
for (Class clazz : SerializableClassRegistry.getRegisteredClasses()) {
conf.registerClass(clazz);
}
}

/**
* 获得 FSTObjectOutput 对象,被 FstObjectOutput 调用
*
* @param outputStream
* @return
*/
public FSTObjectOutput getObjectOutput(OutputStream outputStream) {
return conf.getObjectOutput(outputStream);
}

/**
* 获得 FSTObjectInput 对象,被 FstObjectInput 调用
*
* @param inputStream
* @return
*/
public FSTObjectInput getObjectInput(InputStream inputStream) {
return conf.getObjectInput(inputStream);
}
}

值得注意的是,FST 工厂的构造方法中会将 SerializableClassRegistry 注册表中的待序列化优化类,注册到 FSTConfiguration 中。

FstSerialization

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class FstSerialization implements Serialization {

@Override
public byte getContentTypeId() {
return 9;
}

/**
* 内容类型
* @return
*/
@Override
public String getContentType() {
return "x-application/fst";
}

@Override
public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
return new FstObjectOutput(out);
}

@Override
public ObjectInput deserialize(URL url, InputStream is) throws IOException {
return new FstObjectInput(is);
}
}

实现 Serialization 接口,FST 序列化实现类,将序列化任务交给 FstObjectOutput 对象完成,将反序列化任务交给 FstObjectInput 对象完成。

FstObjectOutput

FstObjectOutput 实现序列化抽象API模块的 ObjectOutput 接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class FstObjectOutput implements ObjectOutput {

private FSTObjectOutput output;

public FstObjectOutput(OutputStream outputStream) {
// 通过工厂创建 FSTObjectOutput 对象
output = FstFactory.getDefaultFactory().getObjectOutput(outputStream);
}

//--------------------- 序列化方法直接委托给 FSTObjectOutput 对应的方法 ---------- /

@Override
public void writeBool(boolean v) throws IOException {
output.writeBoolean(v);
}

@Override
public void writeByte(byte v) throws IOException {
output.writeByte(v);
}

@Override
public void writeShort(short v) throws IOException {
output.writeShort(v);
}

@Override
public void writeInt(int v) throws IOException {
output.writeInt(v);
}

@Override
public void writeLong(long v) throws IOException {
output.writeLong(v);
}

@Override
public void writeFloat(float v) throws IOException {
output.writeFloat(v);
}

@Override
public void writeDouble(double v) throws IOException {
output.writeDouble(v);
}

@Override
public void writeBytes(byte[] v) throws IOException {
if (v == null) {
output.writeInt(-1);
} else {
writeBytes(v, 0, v.length);
}
}

@Override
public void writeBytes(byte[] v, int off, int len) throws IOException {
if (v == null) {
output.writeInt(-1);
} else {
output.writeInt(len);
output.write(v, off, len);
}
}


@Override
public void writeUTF(String v) throws IOException {
output.writeUTF(v);
}

@Override
public void writeObject(Object v) throws IOException {
output.writeObject(v);
}

@Override
public void flushBuffer() throws IOException {
output.flush();
}
}

FstObjectOutput 中的序列化方法直接委托给 FSTObjectOutput 中对应的方法。

FstObjectInput

FstObjectInput 实现序列化抽象API模块的 ObjectInput 接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class FstObjectInput implements ObjectInput {

private FSTObjectInput input;

public FstObjectInput(InputStream inputStream) {
input = FstFactory.getDefaultFactory().getObjectInput(inputStream);
}

// ----------- 所有的实现方法委托给 FSTObjectInput 对应的方法 ---------------/

@Override
public boolean readBool() throws IOException {
return input.readBoolean();
}

@Override
public byte readByte() throws IOException {
return input.readByte();
}

@Override
public short readShort() throws IOException {
return input.readShort();
}

@Override
public int readInt() throws IOException {
return input.readInt();
}

@Override
public long readLong() throws IOException {
return input.readLong();
}

@Override
public float readFloat() throws IOException {
return input.readFloat();
}

@Override
public double readDouble() throws IOException {
return input.readDouble();
}

@Override
public String readUTF() throws IOException {
return input.readUTF();
}

@Override
public Object readObject() throws IOException, ClassNotFoundException {
return input.readObject();
}


@Override
@SuppressWarnings("unchecked")
public <T> T readObject(Class<T> clazz) throws IOException, ClassNotFoundException {
try {
return (T) input.readObject(clazz);
} catch (Exception e) {
throw new IOException(e);
}
}

@Override
@SuppressWarnings("unchecked")
public <T> T readObject(Class<T> clazz, Type type) throws IOException, ClassNotFoundException {
try {
return (T) input.readObject(clazz);
} catch (Exception e) {
throw new IOException(e);
}
}


@Override
public byte[] readBytes() throws IOException {
int len = input.readInt();
if (len < 0) {
return null;
} else if (len == 0) {
return new byte[]{};
} else {
byte[] b = new byte[len];
input.readFully(b);
return b;
}
}
}

每个实现方法,直接委托给 FSTObjectInput 对应的方法。

小结

Dubbo 的 FST 序列化方式特殊点在于可以指定要序列化优化的类,然注册到 FSTConfiguration 配置对象中,用以发挥出 FST 的高性能。其中 Kryo 序列化方式和 FST 类似。其它没有分析到的序列化方式套路都是一样的。Dubbo 的序列化到此结束。