netty概述
原始的NIO使用方式比较繁杂,针对功能不同有不同的使用类和方法(需要掌握selector、serversocketChannel、SocketChannel、ByteBuffer等),与此同时需要考虑多线程情况和网络异常等因素,开发成本较大。jboss提供的netty可以帮助更快的开发一个网络应用,简化了原始nio处理的流程,是目前最流行的nio框架,很多框架的内部也有使用到netty,如dubbo。
对比原始nio优点:①适用于各种传输类型io处理;②灵活扩展(bossgroup和workergroup可定制线程数);③没有繁杂依赖项,netty4.x使用jdk6版本以上就行;④高性能、吞吐量高,最小化不必要的内存复制(零拷贝);⑤社区活跃,版本更新和问题修复及时
架构
传统阻塞I/O服务类型
原理:独立的阻塞IO线程处理 数据的输入->业务处理->数据返回问题:并发数很大的情况下,资源占用过高,并且当连接创建后,在当前线程没有数据读取时,线程会被阻塞,造成资源的浪费
reactor模式
原理:
- 基于IO复用模型:多个连接公用一个阻塞对象,阻塞新创建的连接,当某个连接有新数据可以处理时,线程会从阻塞状态返回,开始业务处理
- 基于线程池复用线程资源:不必为每个连接创建线程,当连接完成,将业务处理分配给线程池中线程处理,一个线程可以处理多个连接的任务
模式分类:单reactor单线程、单reactor多线程、主从reactor多线程
主从reactor多线程:将建立连接accept和处理请求handler分成了两层,主reactor只负责处理连接,多个从reactor负责处理请求
netty的模型选择:主从reactor多线程模型
-bossGroup线程维护selector,只关注accept连接
-接收到连接请求,获取对应的socketChannel,封装成NIOSocketChannel注册到worker线程维护
-worker监听到selector中通道事件,handler处理
NioEventLoopGroup可以有多个线程(NioEventLoop)
boss的NioEventLoop执行步骤
- 轮询accept事件
- 处理连接事件,与客户端建立连接,生成NioSocketChannel,并注册到worker NioEventLoop上的selector处理任务队列
- 处理任务队列任务(连接任务),runAllTasks
worker的NioEventLoop执行步骤
- 轮询read、write请求
- 处理io,在对应的NioSocketChannel处理
- 处理任务队列的任务,runAllTasks
入门案例:
服务端代码,右边是客户端代码。
- ServerBootstrap 类用于创建服务端实例,Bootstrap 用于创建客户端实例。
- handler(…)左边是处理新连接,右边是业务请求处理
- childHandler(…),这里的 handlers 是给新创建的连接用的,我们知道服务端 ServerSocketChannel 在 accept 一个连接以后,需要创建 SocketChannel 的实例,childHandler(…) 中设置的 handler 就是用于处理新创建的 SocketChannel 的,而不是用来处理 ServerSocketChannel 实例的
- pipeline类似于拦截器,每个 NioSocketChannel 或 NioServerSocketChannel 实例内部都会有一个 pipeline 。
- ChannelFuture 是指异步编程,同jdk 里future机制