netty(5)--序列化

netty(5)–序列化

序列化问题

Java 序列化的目的主要有两个:

  • 网络传输

  • 对象持久化

​ 当选行远程跨迸程服务调用时,需要把被传输的 Java 对象编码为字节数组或者ByteBuffer 对象。而当远程服务读取到 ByteBuffer 对象或者字节数组时,需要将其解码为发送时的 Java 对象。这被称为 Java 对象编解码技术。
​ Java 序列化仅仅是 Java 编解码技术的一种,由于它的种种缺陷,衍生出了多种编解码
技术和框架

Java 序列化的缺点

​ Java 序列化从 JDK1.1 版本就已经提供,它不需要添加额外的类库,只需实现java.io.Serializable 并生成序列 ID 即可,因此,它从诞生之初就得到了广泛的应用。但是在远程服务调用(RPC)时,很少直接使用 Java 序列化进行消息的编解码和传输,这又是什么原因呢?下面通过分析.Tava 序列化的缺点来找出答案。

  • 无法跨语言
    对于跨进程的服务调用,服务提供者可能会使用 C 十+或者其他语言开发,当我们需要和异构语言进程交互时 Java 序列化就难以胜任。由于 Java 序列化技术是 Java 语言内部的私有协议,其他语言并不支持,对于用户来说它完全是黑盒。对于 Java 序列化后的字节数组,别的语言无法进行反序列化,这就严重阻碍了它的应用。

  • 序列化后的码流太大
    通过一个实例看下 Java 序列化后的字节数组大小。

  • 序列化性能太低
    无论是序列化后的码流大小,还是序列化的性能,JDK 默认的序列化机制表现得都很差。因此,我们边常不会选择 Java 序列化作为远程跨节点调用的编解码框架。

常用序列化

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));// 添加MarshallingDecoder以将ByteBuf 转换为POJO
        pipeline.addLast(new MarshallingEncoder(marshallerProvider));// 添加MarshallingEncoder 以将POJO转换为ByteBuf
        pipeline.addLast(new ObjectHandler());// 添加ObjectHandler,以处理普通的实现了Serializable 接口的POJO
    }

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

Protocol Buffers

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());// 添加ProtobufVarint32FrameDecoder以分隔帧
          pipeline.addLast(new ProtobufEncoder()); // 添加ProtobufEncoder以处理消息的编码
          pipeline.addLast(new ProtobufDecoder(lite));// 添加ProtobufDecoder以解码消息
          pipeline.addLast(new ObjectHandler());// 添加ObjectHandler以处理解码消息
        }

        public static final class ObjectHandler extends SimpleChannelInboundHandler<Object> {
            @Override
            public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
                // Do something with the object
            }
        }
    }

MessagePack

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值