Netty简介
Netty是一个高性能、高可扩展性的异步事件驱动的网络应用程序框架,它极大地简化了TCP和UDP客户端和服务器开发等网络编程。
Netty四个重要内容:
- Reactor线程模型:一种高性能的多线程程序设计思路
- Netty中自己定义的Channel概念:增强版的通道概念
- ChannelPineline职责链设计模式:事件处理机制
- 内存管理:增强的ByteBuf缓冲区
Netty整体结构图
EventLoopGroup初始化过程:
构造函数-》确定线程数量:默认cous*2-》new Executor:构建线程执行器->for->newChild():构建EventLoop-》new EvenrExecutorChooser
EventLoop的启动
EventLoop自身实现了Executor接口,当调用executor方法提交任务时,则判断是否启动,未启动则调用内置的executor创建新线程来触发run方法执行。
Bind绑定端口过程:
bind(端口):AbstactBootstap->创建和初始化Channel->注册到EventLoop的Selector上->提交任务到EventLoop执行。注册完成后再继续绑定->doBind()->channl.bind->pipeline.bind->HeadContext.bind->AbstarctUsafe.bind->NioServerSocketChannel.doBind
Channel概念:
netty中的Channel是一个抽象的概念,可以理解为对JDKNIO Channel的增强和扩展。增加了很多属性和方法,完整信息可以看代码注释,下面罗列几个常见的属性和方法。
设计模式-责任链模式
责任链模式为请求创建了一个处理对象的链
发起请求和具体处理请求的过程进行解耦:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无需关心请求的处理细节和请求的传递。
实现责任链模式
实现责任链模式4个要素:处理器抽象类、具体的处理器实现类、保存处理器信息、处理执行。
Netty中的ChannelPipeline责任链
Pipeline管道保存了通道所有处理器信息。创建新Channel时自动创建一个专有的pipeline。入站事件和出栈操作会调用pipeline的处理器:
入站事件和出站事件
入站事件:通常指i/o线程生成了入站数据。
(通俗理解:从socket底层自己往上冒上来的事件都是入站)比如EventLoop收到selector的op_read事件,入站处理器调用socektChannel.Read(ByteBuffer)接收到数据后,这将导致通道的ChannelPipeline中包含的下一个中的channelRead方法被调用。
出站事件:经常是指i/o线程执行实际的输出操作。
(通俗理解:想主动往socket底层操作的事件都是出站)比如bind方法用意时请求server socket绑定到给定的SocketAddress,这将导致通道的ChannelPipeline中包含的下一个出站处理器中的bind方法被调用。
下面时netty的事件定义:
Pipeline中的handler是什么
channelHandler:用于处理i/o事件或拦截i/o操作,并转发到ChannelPipeline中国的下一个处理器。这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:
处理入站i/o事件的ChannelinboundHandler处理出站i/o操作的ChannelOutboundHandler
适配器类:为了方便,避免所有handler去实现一遍接口方法,Netty提供了简单的实现类:
ChannelInboundHandlerAdapter处理入站i/o事件
ChannelOutboundHandlerAdapter处理出站i/o事件
ChannelDuolexHandler来支持同时处理入站和出站事件
ChannelHandlerContext:实际存储在pipeline中的对象并非ChannelHandler,而时上下文对象。
将handler,包裹在上下文对象中,通过上下文对象与它所属的ChannelPipeline交互,向上或向下传递事件或者修改pipeline都是通过上下文对象。
维护Pipeline中的Handler
ChannePipeline是线程安全的,ChannelHandler可以在任何时候添加或删除。例如:你可以在即将交换敏感信息时插入加密处理程序,并在交换后删除它。一般操作,初始化的时候增加进去,较少删除。下面是Pipeline管理handler的api