文章目录
初识Netty
Netty简介
Netty是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的、高性能的、面向协议的、服务器和客户端。在网络编程领域,Netty是Java的卓越框架,它驾驭了Java高级API的能力,并将其隐藏在一个易于使用的API之后,通过Netty使得开发者可以专注于自己真正感兴趣的事情,并且不需要太深入的去了解网络编程,也能实现高性能的应用程序。
Netty作为一个框架,它的架构方法和设计原则是:每个小点都和它的技术性内容一样重要,穷其精妙
为什么用Netty
- 对于JAVA NIO模式虽然提供了IO多路复用,但是并没有提供上层"信息格式" 的良好封装。例如并没有提供针对Protocol Buffer、JSON这些信息格式的封装,但是Netty框架提供了这些数据格式封装,例如基于责任链模式的编码和解码功能
- JAVA NIO模式的类库和API相当复杂,使用它来开发,需要非常熟练地掌握 Selector、Buffer、 ServerSocketChannel、SocketChannel、SelectionKey等,并且还需要多线程处理和并发的知识才能很好的使用NIO
- 要编写一个可靠的、易维护的、高性能的NIO服务器应用,除了框架本身要兼容实现各类操作系统的实现外,更重要的是它应该还要处理很多上层特有服务,例如:客户端的权限、信息格式封装、简单的数据读取,断连重连,半包读写,心跳等等,而这些Netty框架都提供了相应的支持
Netty特性总结
(摘自《Netty in Action》)
分类 | 特性 |
---|---|
设计 | 1、统一的AIP,支持多种传输类型,阻塞和非阻塞的 2、简单而强大的线程模型 3、 真正的无连接数据报套接字支持 4、链接逻辑组件以支持复用 |
易于使用 | 1、详细的Javadoc和大量的示例集 2、不需要超过JDK 1.6+的依赖 |
性能 | 1、拥有比Java的核心API更高的吞吐量以及更低的延迟 2、池化和复用,支持更低的资源消耗 3、最少的内存复制 |
健壮性 | 1、不会因为慢速、快速或者超载的连接而导致OOM 2、消除在高速网络中NIO应用程序常见的不公平读/写比率 |
安全性 | 1、完整的SSL/TLS以及StartTLS支持 2、可用于受限环境下,如Applet |
社区驱动 | 1、发布快速而且频繁 |
异步和事件驱动
Netty的异步是建立在Future和回调的概念上的,一个回调其实就是一个方法,一个指向已经被提供给另外一个方法的引用。这使得接受回调的方法可以在适当的时候调用回调方法。回调在广泛的编程场景中都有应用,而且也是在操作完成后通知相关方常见的方法之一。并且Netty使用不同的事件来通知我们状态的改变或者操作的状态,这使得我们能够基于已经发生的事件触发适当的操作
Netty核心组件简介
Channel
Channel是Java NIO的一个基本构造
它代表一个到实体(如一个硬件设备、一个文件、一个网络套接字或者一个能够执行一个或者多个不同的 I/O 操作的程序组件)的开放连接,如读操作和写操作
可以简单的把Channel看作是传入(入站)或者传出(出站)数据的载体。因此,它可以被打开或者被关闭,连接或者断开连接
事件和ChannelHandler
Netty使用不同的事件来通知我们状态的改变或者操作的状态,这使得我们能够基于已经发生的事件来触发适当的动作
Netty事件是按照它们与入站或出站数据流的相关性进行分类的, 可能由入站数据或者相关的状态更改而触发的事件包括:
- 连接已被激活或者连接失活
- 数据读取
- 用户事件
- 错误事件
出站事件是未来将会触发的某个动作的操作结果,这些动作包括:
- 打开或者关闭到远程节点的连接
- 将数据写到或者冲刷到套接字
每个事件都可以被分发给 ChannelHandler 类中的某个用户实现的方法。 Netty提供了大量预定义的可以开箱即用的ChannelHandler实现,包括用于各种协议(如 HTTP 和 SSL/TLS)的 ChannelHandler。
ChannelFuture
Netty中所有的I/O操作都是异步的。因为一个操作可能不会立即返回,所以我们需要一种用于在之后的某个时间点确定其结果的方法。为此,Netty提供了ChannelFuture接口,其addListener()方法注册了一个ChannelFutureListener,以便在某个操作完成时(无论是否成功)得到通知。
可以将ChannelFuture看作是将来要执行的操作的结果的占位符。它究竟什么时候被执行则可能取决于若干的因素,因此不可能准确地预测,但是可以肯定的是它将会被执行。
EventLoop、EventLoopGroup
一个EventLoop由一个永远都不会改变的线程驱动,同时任务可以直接提交给EventLoop实现,以立即执行或者调度执行,根据配置和可用核心的不同,可能会创建多个EventLoop实例用以优化资源的使用,并且单个EventLoop可能会被指派用于服务多个Channel。而EventLoopGroup负责为每个新创建的Channel分配一个EventLoop
所以EventLoop可以简单看成一个线程、EventLoopGroup自然就可以看成一个线程组
第一款Netty应用程序
创建Netty Server
/**
* Netty Server
* @author 11403
*
*/
public class EchoServer {
public final int port;
public EchoServer(int port){
this.port=port;
}
public void startServer(){
//创建服务端的handler
EchoServerHandler handler=new EchoServerHandler();
//创建线程组
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
//指定服务端Bootstrap
ServerBootstrap serverBootstrap=new ServerBootstrap();
//加入线程组
//绑定监听端口
serverBootstrap.group