分布式-高并发-多线程-netty

IO/NIO/AIO & Netty

2017-08-22  本文已影响0人  maven_hz

IO/NIO/AIO 的区别:

Netty

主流的rpc框架都使用了该框架。Hadoop的Avro 、Dubbo 、RocketMQ等。 建议学习网站 http://ifeve.com/netty5-user-guide/

相关原理

        //1 用于接受客户端连接的线程工作组
        EventLoopGroup boss = new NioEventLoopGroup(); //NioEventLoop聚合了多路复用器selector。可处理大量的客户端连接
        //2 用于对接受客户端连接读写操作的线程工作组
        EventLoopGroup work = new NioEventLoopGroup();
        
        //TWO:
        
        //3 辅助类。用于帮助我们创建NETTY服务
        ServerBootstrap b = new ServerBootstrap();
        b.group(boss, work) //绑定两个工作线程组

应用场景

TCP 拆包、粘包解决方案

  1. 消息定长,比如固定为200字节,如果不够,空位补空格
  2. 在包尾部增加特殊字符进行分割,例如回车等
  3. 将消息分为消息头和消息体,在消息头中包含表示消息长度的字段,然后进行业务逻辑处理
/**
*特殊字符分隔方式: 在client端和server端的initChannel中加入配置
*以”$_”为分隔符 
*/
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));

/**
*定长分隔方式: 在client端和server端的initChannel中加入配置
*/
sc.pipeline().addLast(new FixedLengthFrameDecoder(5));

序列化(对象)传输

/**
*client和server端init Chanel时都引入Marshalling转码方法
*/
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
/**
*server端可直接接收对象
*/
Req req = (Req)msg;

注意事项

try{
...
}finally{
ReferenceCountUtil.release(msg);
}

若msg被writeAndFlush发送出去。不需要释放。因为方法中已实现释放代码。
查看源码可发现:

@Override
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
    if (msg == null) {
        throw new NullPointerException("msg");
    }

    if (isNotValidPromise(promise, true)) {
        ReferenceCountUtil.release(msg);//此处被释放
        // cancelled
        return promise;
    }

    write(msg, true, promise);

    return promise;
}
上一篇 下一篇

猜你喜欢

热点阅读