Netty背后的事件驱动机制
Netty简介
Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。
事件驱动模型
通常,我们设计一个事件处理模型的程序有两种思路
轮询方式
线程不断轮询访问相关事件发生源有没有发生事件,有发生事件就调用事件处理逻辑。
事件驱动方式
事件发生时主线程把事件放入事件队列,在另外线程不断循环消费事件列表中的事件,调用事件对应的处理逻辑处理事件。事件驱动方式也被称为消息通知方式,其实是设计模式中观察者模式的思路。
借用O'Reilly大神关于事件驱动模型解释图
主要包括4个基本组件:
事件队列(event queue):接收事件的入口,存储待处理事件
分发器(event mediator):将不同的事件分发到不同的业务逻辑单元
事件通道(event channel):分发器与处理器之间的联系渠道
事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作
可以看到,相对传统轮询模式,事件驱动有如下优点:
可扩展性好,分布式的异步架构,事件处理器之间高度解耦,可以方便扩展事件处理逻辑
高性能,基于队列暂存事件,能方便并行异步处理事件
下图描述了Netty进行事件处理的流程。Channel是连接的通道,是ChannelEvent的产生者,而ChannelPipeline可以理解为ChannelHandler的集合。
事件分为上行(Upstream)和下行(Downstream)两种
当服务器从客户端收到一个消息,那么与之相关的就是一个上行事件(Upstream Event),Pipeline中的UpstreamChannelHandler会处理它;如果服务器要响应这个客户端,那么与响应消息对应的就是下行事件(Downstream Event),Pipeline中的DownstreamChannelHandler会处理它。
ChannelEvent是数据或者状态的载体,例如传输的数据对应MessageEvent,状态的改变对应ChannelStateEvent。当对Channel进行操作时,会产生一个ChannelEvent,并发送到ChannelPipeline。ChannelPipeline会选择一个ChannelHandler进行处理。这个ChannelHandler处理之后,可能会产生新的ChannelEvent,并流转到下一个ChannelHandler。
我们引用Netty官方包里的一个例子,一个简单的EchoServer,它接受客户端输入,并将输入原样返回。
public void run() {
// Configure the server.
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new EchoServerHandler());
}
});
// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(port));
}
EchoServerHandler是这里的业务处理逻辑
public class EchoServerHandler extends SimpleChannelUpstreamHandler {
@Override
public void messageReceived(
ChannelHandlerContext ctx, MessageEvent e) {
// Send back the received message to the remote peer.
e.getChannel().write(e.getMessage());
}
}
其中MessageEvent就是一个事件。这个事件携带了一些信息(ChannelBuffer),例如这里e.getMessage()就是消息的内容,而EchoServerHandler则描述了处理这种事件的方式,一旦某个事件触发,相应的Handler则会被调用,并进行处理(解码成了一个数据对象),并生成了一个新的MessageEvent,并传递给下一步进行处理。
在Netty里,所有事件都来自ChannelEvent接口,这些事件涵盖监听端口、建立连接、读写数据等网络通讯的各个阶段。而事件的处理者就是ChannelHandler,这样,不但是业务逻辑,连网络通讯流程中底层的处理,都可以通过实现ChannelHandler来完成了。事实上,Netty内部的连接处理、协议编解码、超时等机制,都是通过Handler完成的。
技术讨论 & 疑问建议 & 个人博客
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议,转载请注明出处!
参考:https://github.com/code4craft/netty-learning/blob/master/publish/all.md