Skip to content

Commit 2137d50

Browse files
committed
update docs
1 parent eca3107 commit 2137d50

4 files changed

Lines changed: 488 additions & 49 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
1212
- [Dozer 使用指南](docs/javalib/dozer.md)
1313
- [Freemark 使用指南](docs/javalib/freemark.md)
14-
- [细说 Java 主流 JSON](docs/javalib/javalib-json.md)
14+
- [Java JSON](docs/javalib/javalib-json.md)
1515
- [细说 Java 主流日志工具库](docs/javalib/java-log.md)
1616
- [细说 Java 主流工具包](docs/javalib/java-util.md)
1717
- [JavaMail 使用指南](docs/javalib/javamail.md)

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
1212
- [Dozer 使用指南](javalib/dozer.md)
1313
- [Freemark 使用指南](javalib/freemark.md)
14-
- [细说 Java 主流 JSON](javalib/javalib-json.md)
14+
- [Java JSON](javalib/javalib-json.md)
1515
- [细说 Java 主流日志工具库](javalib/java-log.md)
1616
- [细说 Java 主流工具包](javalib/java-util.md)
1717
- [JavaMail 使用指南](javalib/javamail.md)

docs/javalib/javalib-binary.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Java 二进制序列化库
2+
3+
## 简介
4+
5+
### 为什么需要二进制序列化库
6+
7+
原因很简单,就是 Java 默认的序列化机制(`ObjectInputStream``ObjectOutputStream`)具有很多缺点。
8+
9+
> 不了解 Java 默认的序列化机制,可以参考:[Java 序列化](https://github.com/dunwu/javacore/blob/master/docs/io/Java序列化.md)
10+
11+
Java 自身的序列化方式具有以下缺点:
12+
13+
- **无法跨语言使用 **。这点最为致命,对于很多需要跨语言通信的异构系统来说,不能跨语言序列化,即意味着完全无法通信(彼此数据不能识别,当然无法交互了)。
14+
- **序列化的性能不高**。序列化后的数据体积较大,这大大影响存储和传输的效率。
15+
- 序列化一定需要实现 `Serializable` 接口。
16+
- 需要关注 `serialVersionUID`
17+
18+
引入二进制序列化库就是为了解决这些问题,这在 RPC 应用中尤为常见。
19+
20+
### 主流序列化库简介
21+
22+
#### Protobuf
23+
24+
[Protobuf](https://developers.google.com/protocol-buffers/) 是 Google 开发的结构序列化库。
25+
26+
它具有以下特性:
27+
28+
- 结构化数据存储格式(xml,json 等)
29+
- 高性能编解码技术
30+
- 语言和平台无关,扩展性好
31+
- 支持 Java, C++, Python 三种语言
32+
33+
#### Thrift
34+
35+
> [Thrift](https://github.com/apache/thrift) 是 apache 开源项目,是一个点对点的 RPC 实现。
36+
37+
它具有以下特性:
38+
39+
- 支持多种语言(目前支持 28 种语言,如:C++、go、Java、Php、Python、Ruby 等等)。
40+
- 使用了组建大型数据交换及存储工具,对于大型系统中的内部数据传输,相对于 Json 和 xml 在性能上和传输大小上都有明显的优势。
41+
- 支持三种比较典型的编码方式(通用二进制编码,压缩二进制编码,优化的可选字段压缩编解码)。
42+
43+
#### Hessian
44+
45+
> [Hessian](http://hessian.caucho.com/) 是一种二进制传输协议。
46+
>
47+
> RPC 框架 Dubbo 就支持 Thrift 和 Hession。
48+
49+
它具有以下特性:
50+
51+
- 支持多种语言。如:Java、Python、C++、C#、PHP、Ruby 等。
52+
- 相对其他二进制序列化库较慢。
53+
54+
#### Kryo
55+
56+
> [Kryo](https://github.com/EsotericSoftware/kryo) 是用于 Java 的快速高效的二进制对象图序列化框架。Kryo 还可以执行自动的深拷贝和浅拷贝。 这是从对象到对象的直接复制,而不是从对象到字节的复制。
57+
58+
它具有以下特性:
59+
60+
- 速度快,序列化体积小
61+
- 官方不支持 Java 以外的其他语言
62+
63+
#### FST
64+
65+
> [FST](https://github.com/RuedigerMoeller/fast-serialization) 是一个 Java 实现二进制序列化库。
66+
67+
它具有以下特性:
68+
69+
- 近乎于 100% 兼容 JDK 序列化,且比 JDK 原序列化方式快 10 倍
70+
- 2.17 开始与 Android 兼容
71+
- (可选)2.29 开始支持将任何可序列化的对象图编码/解码为 JSON(包括共享引用)
72+
73+
#### 小结
74+
75+
了解了以上这些常见的二进制序列化库的特性。在技术选型时,我们就可以做到有的放矢。
76+
77+
**(1)选型参考依据**
78+
79+
对于二进制序列化库,我们的选型考量一般有以下几点:
80+
81+
- **是否支持跨语言**
82+
- 根据业务实际需求来决定。一般来说,支持跨语言,为了兼容,使用复杂度上一般会更高一些。
83+
- **序列化、反序列化的性能**
84+
- **类库是否轻量化,API 是否简单易懂**
85+
86+
**(2)选型建议**
87+
88+
- 如果需要跨语言通信,那么可以考虑:Protobuf、Thrift、Hession。
89+
- [thrift](https://github.com/apache/thrift)[protobuf](https://github.com/protocolbuffers/protobuf) - 适用于对性能敏感,对开发体验要求不高的内部系统。
90+
- [hessian](http://hessian.caucho.com/doc/hessian-overview.xtp) - 适用于对开发体验敏感,性能有要求的内外部系统。
91+
92+
- 如果不需要跨语言通信,可以考虑:[Kryo](https://github.com/EsotericSoftware/kryo)[FST](https://github.com/RuedigerMoeller/fast-serialization),性能不错,且 API 十分简单。
93+
94+
## FST 应用
95+
96+
### 引入依赖
97+
98+
```xml
99+
<dependency>
100+
<groupId>de.ruedigermoeller</groupId>
101+
<artifactId>fst</artifactId>
102+
<version>2.56</version>
103+
</dependency>
104+
```
105+
106+
### FST API
107+
108+
示例:
109+
110+
```java
111+
public class FstDemo {
112+
113+
private static FSTConfiguration DEFAULT_CONFIG = FSTConfiguration.createDefaultConfiguration();
114+
115+
public static <T> byte[] serialize(T obj) {
116+
return DEFAULT_CONFIG.asByteArray(obj);
117+
}
118+
119+
public static <T> T deserialize(byte[] bytes, Class<T> clazz) throws IOException {
120+
Object obj = DEFAULT_CONFIG.asObject(bytes);
121+
if (clazz.isInstance(obj)) {
122+
return (T) obj;
123+
} else {
124+
throw new IOException("derialize failed");
125+
}
126+
}
127+
128+
}
129+
```
130+
131+
测试:
132+
133+
```java
134+
// 序列化
135+
byte[] bytes = JdkSerializeDemo.serialize(oldBean);
136+
// 反序列化
137+
TestBean newBean = JdkSerializeDemo.deserialize(bytes, TestBean.class);
138+
```
139+
140+
## TODO
141+
142+
## 参考资料
143+
144+
- **官方**
145+
- [Protobuf 官网](https://developers.google.com/protocol-buffers/)
146+
- [Protobuf Github](https://github.com/protocolbuffers/protobuf)
147+
- [Thrift Github](https://github.com/apache/thrift)
148+
- [Kryo Github](https://github.com/EsotericSoftware/kryo)
149+
- [Hessian 官网](http://hessian.caucho.com/)
150+
- [FST Github](https://github.com/RuedigerMoeller/fast-serialization)
151+
- **文章**
152+
- [java序列化框架对比](https://www.jianshu.com/p/937883b6b2e5)

0 commit comments

Comments
 (0)