005——Netty之EventLoop与EventLoopGroup

Netty解决的事情

Netty主要解决两个相应关注领域。(1)异步和事件驱动的实现。(2)一组设计模式,将应用逻辑与网络层解耦。

EventLoop接口

用于处理连接的生命周期中所发生的事件。

  • 一个EventLoopGroup包含一个或者多个EventLoop
  • 一个EventLoop在它的生命周期内只和一个Thread绑定
  • 所有由EventLoop处理的I/O事件都将在它专有的Thread上被处理
  • 一个Channel在它的生命周期内只注册于一个EventLoop
  • 一个EventLoop可能会被分配给一个或者多个Channel

Netty NIO 客户端

// 创建一个 EventLoopGroup 对象
EventLoopGroup group = new NioEventLoopGroup();
// 创建 Bootstrap 对象
Bootstrap b = new Bootstrap();
// 设置使用的 EventLoopGroup
b.group(group);
  • Netty只创建一个EventLoop
  • 一个EventLoop可以对应一个Reactor
  • 一个 Bootstrap 的启动,只能发起对一个远程的地址。所以只会使用一个 NIO Selector ,也就是说仅使用一个 Reactor 。即使,我们在声明使用一个 EventLoopGroup ,该 EventLoopGroup 也只会分配一个 EventLoop 对 IO 事件进行处理。

Netty NIO 服务端

// 创建两个 EventLoopGroup 对象
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 创建 boss 线程组 用于服务端接受客户端的连接
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 创建 worker 线程组 用于进行 SocketChannel 的数据读写
// 创建 ServerBootstrap 对象
ServerBootstrap b = new ServerBootstrap();
// 设置使用的 EventLoopGroup
b.group(bossGroup, workerGroup);
  • bossGroup 对应 Reactor 模式的 mainReactor ,用于服务端接受客户端的连接。比较特殊的是,传入了方法参数 nThreads = 1 ,表示只使用一个 EventLoop ,即只使用一个 Reactor 。这个也符合我们上面提到的,“通常,mainReactor 只需要一个,因为它一个线程就可以处理”。
  • workerGroup 对应 Reactor 模式的 subReactor ,用于进行 SocketChannel 的数据读写。对于 EventLoopGroup ,如果未传递方法参数 nThreads ,表示使用 CPU 个数 Reactor 。这个也符合我们上面提到的,“通常,subReactor 的个数和 CPU 个数相等,每个 subReactor 独占一个线程来处理”。

Netty中的Reactor模型

  • 处理链中的处理方法是串行化执行的
  • 一个客户端连接只注册到一个NioEventLoop上,避免了多个IO线程并发操作

流程:

① 注册一个Acceptor事件处理器到mainReactor中,Acceptor事件处理器所关注的事件是ACCEPT事件,这样mainReactor会监听客户端向服务器端发起的连接请求事件(ACCEPT事件)。启动mainReactor的事件循环。

② 客户端向服务器端发起一个连接请求,mainReactor监听到了该ACCEPT事件并将该ACCEPT事件派发给Acceptor处理器来进行处理。Acceptor处理器通过accept()方法得到与这个客户端对应的连接(SocketChannel),然后将这个SocketChannel传递给subReactor线程池。

③ subReactor线程池分配一个subReactor线程给这个SocketChannel,即,将SocketChannel关注的READ事件以及对应的READ事件处理器注册到subReactor线程中。当然你也注册WRITE事件以及WRITE事件处理器到subReactor线程中以完成I/O写操作。Reactor线程池中的每一Reactor线程都会有自己的Selector、线程和分发的循环逻辑。

④ 当有I/O事件就绪时,相关的subReactor就将事件派发给响应的处理器处理。注意,这里subReactor线程只负责完成I/O的read()操作,在读取到数据后将业务逻辑的处理放入到线程池中完成,若完成业务逻辑后需要返回数据给客户端,则相关的I/O的write操作还是会被提交回subReactor线程来完成。

Netty 与 Reactor模式

Netty的线程模式就是一个实现了Reactor模式的经典模式。

结构对应:

NioEventLoop ———— Initiation Dispatcher

Synchronous EventDemultiplexer ———— Selector

Evnet Handler ———— ChannelHandler

ConcreteEventHandler ———— 具体的ChannelHandler的实现

模式对应:

Netty服务端使用了“多Reactor线程模式”

mainReactor ———— bossGroup(NioEventLoopGroup) 中的某个NioEventLoop

subReactor ———— workerGroup(NioEventLoopGroup) 中的某个NioEventLoop

acceptor ———— ServerBootstrapAcceptor

ThreadPool ———— 用户自定义线程池

参考:

https://www.cnblogs.com/winner-0715/p/8733787.html

http://svip.iocoder.cn/Netty/EventLoop-1-Reactor-Model

原文地址:https://www.cnblogs.com/boycelee/p/10014422.html

时间: 2024-10-08 19:35:07

005——Netty之EventLoop与EventLoopGroup的相关文章

Netty学习之核心组件(EventLoop、EventLoopGroup)

一.EventLoop.EventLoopGroup概述 由下图所示,NioEventLop是EventLoop的一个具体实现,EventLoop是EventLoopGroup的一个属性,NioEventLoopGroup是EventLoopGroup的具体实现,都是基于ExecutorService进行的线程池管理,因此EventLoop.EventLoopGroup组件的核心作用就是进行Selector的维护以及线程池的维护. 其中EventLoop进行的是Selector的维护,如下图左:

Netty源码学习——EventLoopGroup原理:NioEventLoopGroup分析

类结构图: 不了解Executor接口原理的可以查看concurrent包中的api介绍,这里只介绍Netty中EventExecutorGroup的主要功能! 从类的结构图中可以看到EventExecutorGroup是直接继承ScheduledExecutorService这个接口的,为了说明白Group的原理这里顺便提一下ScheduledExecutorService的用途! java.util.concurrent.ScheduledExecutorService An Executo

6. Netty源码分析之EventLoop与EventLoopGroup

一.NioEventLoop与NioEventLoopGroup的关系 二.NioEventLoop 1. 设计原理 1. 负责IO读写 2. 执行task.通过调用NioEventLoop的execute(Runnable task)方法实现.我们知道,为了防止资源竞争和并发操作,我们经常会判断当前操作线程是否为EventLoop线程,如果不是,则将操作封装成task放进NioEventLoop的执行队列中,这样就实现了局部无锁化. 3. 定时任务.通过调用NioEventLoop的sched

Netty in Action (十七) 第七章节 EventLoop和线程模型

本章节包括: 1)线程模型总览 2)Event Loop概念和具体实现 3)任务调度 4)实现细节 简单地陈述一下,对于一个操作系统,编程语言,框架,或者应用来说,线程模型对其都是至关重要的一部分,在什么时间如何创建一个线程都会对你的代码执行有很重要的影响,所以对于开发人员而言,懂得在各种线程模型里面权衡利弊就是一个很重要的事情,是直接使用线程模型本身还是通过一些框架或者语言提供的线程框架对于开发者而言都是需要选择的 在这个章节,我们将会详细地讲解Netty的线程模型,这个模型是很强大的,且易于

Netty实战七之EventLoop和线程模型

简单地说,线程模型指定了操作系统.编程语言.框架或者应用程序的上下文中的线程管理的关键方面.Netty的线程模型强大但又易用,并且和Netty的一贯宗旨一样,旨在简化你的应用程序代码,同时最大限度地提高性能和可维护性. 1.线程模型概述 线程模型确定了代码的执行方式,由于我们总是必须规避并发执行可能会带来的副作用,所以理解所采用的并发模型(也有单线程的线程模型)的影响很重要. 因为具有多核心或多个CPU的计算机现在已经司空见惯,大多数的现代应用程序都利用了复杂的多线程处理技术以有效地利用系统资源

netty源码解解析(4.0)-6 线程模型-IO线程EventLoopGroup和NIO实现(一)

接口定义 io.netty.channel.EventLoopGroup extends EventExecutorGroup 方法 说明 ChannelFuture register(Channel channel) 把一个channel注册到一个EventLoop ChannelFuture register(Channel channel, ChannelPromise promise); 同上 io.netty.channel.EventLoop extends OrderedEvent

Netty权威指南

Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-23343-2 2014年6月出版 定价:79.00元 524页 16开 编辑推荐 - 资深一线专家诚意之作,总结多年实践经验,带你全面掌握Java高并发异步通信的首选框架——Netty. - Facebook.阿里巴巴.1号店.并发编程网.JBoss等多位资深技术专家联名力荐. <Netty权威指南>

(二)Netty学习笔记之服务端启动

本文将不会对netty中每个点分类讲解,而是一个服务端启动的代码走读,在这个过程中再去了解和学习,这也是博主自己的学习历程.下面开始正文~~~~ 众所周知,在写netty服务端应用的时候一般会有这样的启动代码: (代码一) 1 EventLoopGroup bossGroup = new NioEventLoopGroup(1); 2 EventLoopGroup workerGroup = new NioEventLoopGroup(); 3 try { 4 ServerBootstrap b

Netty4具体解释三:Netty架构设计

     读完这一章,我们基本上能够了解到Netty全部重要的组件,对Netty有一个全面的认识.这对下一步深入学习Netty是十分重要的,而学完这一章.我们事实上已经能够用Netty解决一些常规的问题了. 一.先纵览一下Netty.看看Netty都有哪些组件? 为了更好的理解和进一步深入Netty.我们先整体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作的.Netty应用中不可缺少的组件: Bootstrap or ServerBootstrap EventLoop E