This repository has been archived by the owner on Jul 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 167
Customized Encoding
linux_china edited this page Mar 9, 2021
·
8 revisions
目前RSocket Broker在Java的Responder端提供以下序列化格式,并且服务提供端能够针对请求端的要求自行进行数据序列化适配。
- Hessian: Java应用默认的数据序列化格式
- JSON: JSON,如果你从Node或者浏览器端接入,建议使用JSON。
- Google Protobuf: Google Protobuf,如果你非常关注性能,而且不在意idl编写方式,可以考虑Protobuf
- Cbor: CBOR格式 https://cbor.io/
- Avro: Kafka主要采用Avro,可以考虑这种方式
- Java Object: Java原生Object序列化方式
- String: 基于UTF-8的字符串序列化
- CloudEvents: 支持CloudEvent单参数序列化
考虑到真实的场景中还有不少其他数据格式序列化的需求,也就是Customized Encoding,所以Alibaba RSocket Broker提供了自定义数据序列化。 步骤如下:
- 创建一个Java类,实现ObjectEncodingHandler接口,如你打算采用SBE(Simple Binary Encoding)进行数据序列化,就创建ObjectEncodingHandlerSbeImpl类,然后实现对应的逻辑
- 根据Java的ServiceLoader机制,进行Services加载。在资源目录下创建META-INF/services/com.alibaba.rsocket.encoding.ObjectEncodingHandler文件,然后输入ObjectEncodingHandlerSbeImpl对应类的全名
alibaba-rsocket-core会通过ServiceLoader机制自动完成自定义序列格式处理类的加载,并在通讯过程中进行数据自动序列化和反序列化。
RSocket已经支持单个Payload的数据编码设置,你可以参考 Stream Data MIME Types Metadata Extension
上述的格式同样多多语言场景有效,你只需要按照RSocket标准协议进行设置即可。
不少Java框架都使用Hessian进行对象序列化,如Dubbo, Sofa等。 Alibaba RSocket Broker从Dubbo Hessian Lite中copy相关的handler,这样做的目的主要是数据格式兼容,可以实现RSocket和Dubbo直接相互调用。 主要提升点有以下:
- 删除了反射相关的代码,RSocket支持的Java版本是1.8+,而且反射操作影响性能。
- 使用Hessian标准的Serializer扩展,也就是META-INF/hessian/serializers中添加自定义Serializer
- 添加了Optional支持
还进行了其他方面的一些测试,仅供参考:
- 如果你在使用Joda Time,我们建议你切换到Java 8 Time或者扩展Joda Time对应的Serializer,Hessian会自动进行加载。
- 对于使用Kotlin的同学来说,我们建议你自行扩展Hessian支持,如Range、Pair、Triple、Result、UInt、ULong等等。
- 我看到有同学反馈Emoji的问题,测试中4个字节的Emoji支持没有问题的。
private String emojiBear = "我是🐻";
- JDK 14的Records支持,这个没有问题,还是一样的写法,如果要添加Json序列化支持(Jackson),需要添加对应的@JsonProperty,同时implements Serializable接口
public record UserRecord(@JsonProperty("id") Integer id, @JsonProperty("name") String name) implements Serializable {
}
Alibaba RSocket Broker支持CloudEvents规范的CloudEvent接口,你可以在函数声明中使用CloudEvent作为参数类型或者返回值类型,代码如下:
Mono<CloudEvent> processLoginEvent(CloudEvent loginEvent);
注意: 目前支持CloudEvent类型作为函数的唯一参数,如果函数包含多个参数,其中一个参数为CloudEvent,这种情况是不支持的。
- Binary: byte stream
- Async message
- Multi transports
- Reactive Semantics
- request/response
- request/stream
- fire-and-forget
- channel
- TCP+TLS
- WebSocket+TLS
- UDP(Aeron)
- RDMA