Netty序列化數(shù)據(jù)

2018-08-08 10:44 更新

在JDK中是使用了 ObjectOutputStream 和 ObjectInputStream 來通過網(wǎng)絡(luò)將原始數(shù)據(jù)類型和 POJO 進行序列化和反序列化,API并不復(fù)雜,支持 java.io.Serializable 接口,但是它也不算是高效的。本節(jié)內(nèi)容中,我們來看看 Netty 所提供的。  

JDK 序列化

如果程序與端對端間的交互是使用 ObjectOutputStream 和 ObjectInputStream,并且主要面臨的問題是兼容性,那么, JDK 序列化 是不錯的選擇。

表8.8列出了序列化類,Netty 提供了與 JDK 的互操作。

Table 8.8 JDK Serialization codecs

名稱描述
CompatibleObjectDecoder該解碼器使用 JDK 序列化,用于與非 Netty 進行互操作。
CompatibleObjectEncoder該編碼器使用 JDK 序列化,用于與非 Netty 進行互操作。
ObjectDecoder基于 JDK 序列化來使用自定義序列化解碼。外部依賴被排除在外時,提供了一個速度提升。否則選擇其他序列化實現(xiàn)
ObjectEncoder基于 JDK 序列化來使用自定義序列化編碼。外部依賴被排除在外時,提供了一個速度提升。否則選擇其他序列化實現(xiàn)

JBoss Marshalling 序列化

如果可以使用外部依賴 JBoss Marshalling 是個明智的選擇。比 JDK 序列化快3倍且更加簡練。

JBoss Marshalling 是另一個序列化 API,修復(fù)的許多 JDK序列化 API 中發(fā)現(xiàn)的問題,它與 java.io.Serializable 完全兼容。并添加了一些新的可調(diào)參數(shù)和附加功能,所有這些都可插入通過工廠配置外部化,類/實例查找表,類決議,對象替換,等等)

下表展示了 Netty 支持 JBoss Marshalling 的編解碼器。

Table 8.9 JBoss Marshalling codecs

名稱描述
CompatibleMarshallingDecoder為了與使用 JDK 序列化的端對端間兼容。
CompatibleMarshallingEncoder為了與使用 JDK 序列化的端對端間兼容。
MarshallingDecoder使用自定義序列化用于解碼,必須使用

MarshallingEncoder MarshallingEncoder | 使用自定義序列化用于編碼,必須使用 MarshallingDecoder

下面展示了使用 MarshallingDecoder 和 MarshallingEncoder

Listing 8.13 Using JBoss Marshalling

public class MarshallingInitializer extends ChannelInitializer<Channel> {

    private final MarshallerProvider marshallerProvider;
    private final UnmarshallerProvider unmarshallerProvider;

    public MarshallingInitializer(UnmarshallerProvider unmarshallerProvider,
                                  MarshallerProvider marshallerProvider) {
        this.marshallerProvider = marshallerProvider;
        this.unmarshallerProvider = unmarshallerProvider;
    }
    @Override
    protected void initChannel(Channel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        pipeline.addLast(new MarshallingDecoder(unmarshallerProvider));
        pipeline.addLast(new MarshallingEncoder(marshallerProvider));
        pipeline.addLast(new ObjectHandler());
    }

    public static final class ObjectHandler extends SimpleChannelInboundHandler<Serializable> {
        @Override
        public void channelRead0(ChannelHandlerContext channelHandlerContext, Serializable serializable) throws Exception {
            // Do something
        }
    }
}

ProtoBuf 序列化

ProtoBuf 來自谷歌,并且開源了。它使編解碼數(shù)據(jù)更加緊湊和高效。它已經(jīng)綁定各種編程語言,使它適合跨語言項目。

下表展示了 Netty 支持 ProtoBuf 的 ChannelHandler 實現(xiàn)。

Table 8.10 ProtoBuf codec

名稱描述
ProtobufDecoder使用 ProtoBuf 來解碼消息
ProtobufEncoder使用 ProtoBuf 來編碼消息
ProtobufVarint32FrameDecoder在消息的整型長度域中,通過 "Base 128 Varints"將接收到的 ByteBuf 動態(tài)的分割

用法見下面

Listing 8.14 Using Google Protobuf

public class ProtoBufInitializer extends ChannelInitializer<Channel> {

    private final MessageLite lite;

    public ProtoBufInitializer(MessageLite lite) {
        this.lite = lite;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ProtobufVarint32FrameDecoder());
        pipeline.addLast(new ProtobufEncoder());
        pipeline.addLast(new ProtobufDecoder(lite));
        pipeline.addLast(new ObjectHandler());
    }

    public static final class ObjectHandler extends SimpleChannelInboundHandler<Object> {
        @Override
        public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
            // Do something with the object
        }
    }
}
  1. 添加 ProtobufVarint32FrameDecoder 用來分割幀
  2. 添加 ProtobufEncoder 用來處理消息的編碼
  3. 添加 ProtobufDecoder 用來處理消息的解碼
  4. 添加 ObjectHandler 用來處理解碼了的消息

本章在這最后一節(jié)中,我們探討了 Netty 支持的不同的序列化的專門的解碼器和編碼器。這些是標準 JDK 序列化 API,JBoss Marshalling 和谷歌ProtoBuf。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號