Netty实战

Netty实战

一个既是异步又是事件驱动的系统会表现出一个极具价值的行为:可以以任意的顺序响应在任意的时间点产生的事件。

  • 非阻塞网络调用使我们不必等待一个操作的完成,异步方法会立即返回并且在他完成时,会直接或者在稍后的某个时间点通知用户。ChannelFuture(异步) + FutureListener(回调)
  • 选择器使得我们能够通过较少的线程监视许多连接上的事件并派发处理。selector + channelhandler

Netty的数据容器ByteBuf

directbuf堆外缓冲区,依然是用户态内存,不由数组支撑,如果使用的话,应该分配一个具有同样长度的字节数组,将directbuf复制进去

Channel、ChannelHandler

channel的生命周期:
channelregistered:被注册到eventloop
ChanneActive:处于活动状态(已连接),可以接收发送数据

ChannelFuture和ChanelPromise
当一个promise完成后,future便不再可变。ChannelOutboundHandler大部分方法都需要一个promise,以便在操作完成时得到通知
ChannelPromis还提供立刻通知的可写方法 setSuccess() setFailure()

资源管理
ChanelInboundHandler 的 channelRead()需要显式地释放池化ByteBuf相关的内存,调用release方法
而SimpleChannelInboundHandler的channelRead0()不需要,其会自动的释放资源,所以如果在这个方法里调用write是不合适的,由于异步,可能资源还拷贝用完就被释放掉了。
在write里释放资源,还要通知ChannelPromise,否则会出现ChannelFutureListener收不到某个消息已经被处理了的通知

write
调用channel.write或者pipeline.write流向都是从尾端到头部。
调用ctx.write(channelHandlerContext)流向则是从当前ctx发送到下一个ChannelHandler

异常处理
exceptionCaught 异常处理方法

  1. 入站异常:因为所有异常会按照入站方向流动,所以默认实现是将当前异常抛给下一个ChannelHandler,实现此方法的ChannelHandler通常在最后,确保异常都可以捕获处理
  2. 出站异常:基于通知机制:几乎每个ChannelOutboundHandler上的方法都会传入一个ChannelPromise,可以被分配用于异步通知的监听器ChannelFutureListener
    比如channel.write方法返回一个future对象,addListener(),重写operationComplete方法,处理异常或者完成通知关闭channel等等操作
    或者重写ChannelOutboundHandler的write方法时,其传参为ctx,msg,promise,在其promise上addListener

EventLoop及线程模型

EventLoop事件循环,采用两个基本的API:并发concurrent和网络编程netty.channel
绑定一个线程,有点线程池单线程的味道,处理task任务,不过毕竟有自身自己的任务,还要selector、handler。事件和任务的执行都是FIFO先进先出的顺序被处理。
所有的IO操作和handler都由这个线程处理,触发可以由其他线程触发,比如write,但是从源码分析可以看出,write方法会判断线程是否属于EventLoop,如果不是,需要将write任务提交到task队列,还是由EventLoop对应的thread处理。毕竟socketchannel被好几个线程write可能会出现多线程并发问题,所以应该规避。Netty4的线程模型是在同一个线程中处理某个给定的EventLoop的所有事件。

JDK的定时任务调度会有额外的线程创建new ScheduledThreadPool(),而netty会将任务提交到此线程对应的定时任务队列

编解码器

ByteToMessageCodec

解码器

  1. ByteToMessageDecoder
    从ByteBuf in读取readInt,每次还要判断字节数,Int是4个,判断一下是否大于4个字节,输出到List out ;传递给下一个ChannelInboundHandler时候就是解码对应的类型了,比如Integer啥的
    会重复调用,直到没有新的元素添加到List中

  2. ReplayingDecoder
    不需要自己判断字节数是否满足条件

  3. MessageToMessageDecoder
    比如将之前已经转化好的Integer转化为String

编码器

MessageToByteEncoder
将泛型msg作为参数写入out,即out.writeShort(msg) 转化为Short类型并输出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值