Netty是什么编程
大概用Netty的,不管新手仍是老手,都知道它是一个“网络通信框架”。所谓框架,基本上都是一个做用:基于底层API,提供更便捷的编程模型。那么"通信框架"到底作了什么事情呢?回答这个问题并不太容易,咱们不妨反过来看看,不使用netty,直接基于NIO编写网络程序,你须要作什么(以Server端TCP链接为例,这里咱们使用Reactor模型):bootstrap
创建线程是一个比较耗时的操做,同时维护线程自己也有一些开销,因此咱们会须要多线程机制,幸亏JDK已经有很方便的多线程框架了,这里咱们不须要花不少心思。网络
此外,由于TCP链接的特性,咱们还要使用链接池来进行管理:多线程
创建TCP链接是比较耗时的操做,对于频繁的通信,保持链接效果更好
对于并发请求,可能须要创建多个链接
维护多个链接后,每次通信,须要选择某一可用链接
链接超时和关闭机制
想一想就以为很复杂了!实际上,基于NIO直接实现这部分东西,即便是老手也容易出现错误,而使用Netty以后,你只须要关注逻辑处理部分就能够了。并发
体验Netty框架
这里咱们引用Netty的example包里的一个例子,一个简单的EchoServer,它接受客户端输入,并将输入原样返回。其主要代码以下:ide
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()); } }
仍是挺简单的,不是吗?工具
Netty背后的事件驱动机制学习
完成了以上一段代码,咱们算是与Netty进行了第一次亲密接触。若是想深刻学习呢?ui
阅读源码是了解一个开源工具很是好的手段,可是Java世界的框架大多追求大而全,功能完备,若是逐个阅读,不免迷失方向,Netty也并不例外。相反,抓住几个重点对象,理解其领域概念及设计思想,从而理清其脉络,至关于打通了任督二脉,之后的阅读就再也不困难了。
理解Netty的关键点在哪呢?我以为,除了NIO的相关知识,另外一个就是事件驱动的设计思想。什么叫事件驱动?咱们回头看看 EchoServerHandler 的代码,其中的参数: public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) ,MessageEvent就是一个事件。这个事件携带了一些信息,例如这里 e.getMessage() 就是消息的内容,而 EchoServerHandler 则描述了处理这种事件的方式。一旦某个事件触发,相应的Handler则会被调用,并进行处理。这种事件机制在UI编程里普遍应用,而Netty则将其应用到了网络编程领域。
在Netty里,全部事件都来自 ChannelEvent 接口,这些事件涵盖监听端口、创建链接、读写数据等网络通信的各个阶段。而事件的处理者就是 ChannelHandler ,这样,不可是业务逻辑,连网络通信流程中底层的处理,均可以经过实现 ChannelHandler 来完成了。事实上,Netty内部的链接处理、协议编解码、超时等机制,都是经过handler完成的。当博主弄明白其中的奥妙时,不得不佩服这种设计!
下图描述了Netty进行事件处理的流程。 Channel 是链接的通道,是ChannelEvent的产生者,而 ChannelPipeline 能够理解为ChannelHandler的集合。
开启Netty源码之门
理解了Netty的事件驱动机制,咱们如今能够来研究Netty的各个模块了。Netty的包结构以下:
org └── jboss └── netty ├── bootstrap 配置并启动服务的类 ├── buffer 缓冲相关类,对NIO Buffer作了一些封装 ├── channel 核心部分,处理链接 ├── container 链接其余容器的代码 ├── example 使用示例 ├── handler 基于handler的扩展部分,实现协议编解码等附加功能 ├── logging 日志 └── util 工具类
在这里面, channel 和 handler 两部分比较复杂。咱们不妨与Netty官方的结构图对照一下,来了解其功能。
具体的解释能够看这里: http://netty.io/3.7/guide/#ar... 。图中能够看到,除了以前说到的事件驱动机制以外,Netty的核心功能还包括两部分:
此外,Protocol Support功能经过handler机制实现。