本文详细介绍了反应堆网络编程模型的概念以及三个反应堆网络编程模型。
早些时候,我们在Java中介绍了四个通用网络IO模型:Java的四个通用网络IO模型,并简要介绍了Select,Poll,Epoll函数。重复使用方式。
通用网络编程模型不是四个最基本的网络IO模型,因为这涉及基础代码的编写。基于基本网络IO模型,大型家伙使用面向对象的方法进一步封装了诸如反应器,ProCractor,受体连接器之类的编程模型。反应器模型是最常见的网络编程模型。著名的帧或软件(例如Netty,Tomcat等)使用反应堆模型来实现高频率和高性能网络通信。
Java复杂编程的父亲Doug Lea在多年前解释了反应堆模型:http://gee.cs.oswego.edu.edu/dl/cpjslides/nio.pdf,Java Nio软件包是最简单的基于最简单的反应堆模型已实施,道格·莉亚(Doug Lea)的文章中也给出了一些用例。
我们以前已经研究了IO多路响亮模型,并且有两个主要好处:首先,该模型可以在同一线程中同时监视多个IO请求。该系统不需要创建大量线程,这大大降低了系统的支出,其次是等待等待的方法可以减少无效的系统调用并减少CPU资源的消耗。
反应堆模型是IO多路重用模型的面向对象的软件包。它不仅允许用户考虑基础网络API的详细信息,而且只需要注意应用程序代码的编写。反应器字面翻译是反应器。此处的反应是指对事件的响应:当IO多路重用程序监视器并接收事件通知时,它会根据事件类型的类型分配给不同的处理器。DISPATCHER模型或基于事件的模型。
反应堆模型可以抽象两个重要组成部分:
自反应堆模型的开发以来,它包含各种实现。通用单反应堆单线线程模式,单反应堆多线程模式和多反应器多线程模式。
Doug Lea文章中给出的模式的流程图如下:
在上图中,反应器用于监视各种IO事件,并分配给特定处理程序。Accepter组件专门用于处理连接事件的建立。它可以被视为特殊处理程序。
总体过程是:
单个反应堆单线线程模式的含义是上述反应堆和柄的所有操作均在同一线程中完成。上面的选择,接受,读取,wtite和其他呼叫以及其他呼叫以及业务逻辑处理均在同一线程中完成。
单反应堆单线线程模式是最基本的反应堆模型,更简单地实现。因为它是一个线程,因此无需考虑任何并发问题。
但是,单个反应堆单线线程模式只有一项线程工作,无法充分利用现代多核CPU的性能,如果客户端的业务逻辑花费很长时间,它将导致后续其他客户端的服务请求阻塞执行。
由于Redis的业务处理主要在内存中完成,因此内存操作速度很快,并且REDIS性能瓶颈不在CPU上(在网络IO的消耗和内存上)。6之前,该命令的执行也是单个反应器单个反应器- 线程模型。
但是,在redis 6之后,引入了多线程机制(多线程真实香),但是仅在Internet io data的读取-write操作中使用多线程多线程线程。一个单行序列,因此无需担心REDIS的线程安全问题。
Doug Lea文章中给出的单反应器单线程模式的伪代码如下:
反应堆:
处理者:
为了克服无法在单个线程模型下使用多核CPU的优势,以及由于请求的长期执行时间而导致的后续请求io封锁问题,单个反应器多线程模型是发达。
Doug Lea文章中给出的模式的流程图如下:
在上图中,单个反应器线程用于监视各种IO事件,并分配给特定的处理程序。这与单个反应堆单线线程模型相同。NON-IO操作(除读取和发送呼叫以外的业务操作)是从反应堆线程转移到工作线程池以执行并发性的。
总体过程是:
在此模式下,其他业务逻辑除了在处理程序期间读取和发送呼叫以外的其他业务逻辑由Multi -Threaded执行。由于一段时间耗尽的业务逻辑,它不会延迟后续IO请求的处理。
此模式可以充分利用多核CPU性能,但会带来多线程并发问题。商业逻辑的写作需要特别注意共享数据的处理。
此外,尽管业务处理在此模型中使用异步执行,但效率得到了提高,但它仍然使用单个反应器线程来进行所有事件的监视和基本IO操作,例如接受,读取,发送和连接操作当成千上万的连接高现货场景仍然成为性能瓶颈时。
Doug Lea文章中给出的单反应器多线模式给出的伪编码如下:
处理程序类已成为支持多线程处理业务的MthreadHandler。反应堆类并没有太大变化。在受体中,新处理程序已成为新的MthreadHandler:
为了防止单个反应堆成为瓶颈,我们可以继续将反应器的功能转换为两个部分:“连接客户端”和“与客户端的通信”。模式,也称为反应器mainstorphic多线程模式。
Doug Lea文章中给出的模式的流程图如下:
MainreActor拥有自己的选择器,该选择器专门通过选择连接来建立事件。事件准备就绪后,通过受体对象中的访问对象与客户端访问。然后将新连接分配给子效率。主体也有自己的选择器。在中间,连接继续监视和执行其他事件,例如阅读和写作,以便将反应器的工作分为两个部分。这两个部分可以在独立线程中执行,以进一步提高性能。
总体过程是:
在多反应器多线程模式下,MainreActor和subepealctor可以具有多个。每个都有自己的选择器,并在独立线程中起作用。这进一步使用了多核多线程优势,因此反应堆很容易变得容易变得容易变得容易变得容易变得容易变得容易变得容易变得容易变得容易变得轻松地变得易于瓶颈,从而提高了连接速度和IO阅读速度和写作。
但是多反应器多线程模式仍然无法解决时间对其他客户端的io操作的效果,因为子发电机可能仍然对应于多个客户端连接。为此,您可以使用真实的异步IO模型Evolution.design模式 - 实施器模式以实现真实的异步IO。
Netty和Memcached都是多反应器多线程模式。NGINX还采用了多反应器Multi -Process模式。subeActor处理业务的执行,而IO操作(例如读取和写入),即工人的线程池或subReactor and worker threads在线程池中的执行:
Netty可以通过配置参数支持反应堆单线线程模型和多线模型。默认模式下的多反应器多线程模式变体。
Doug Lea文章中给出的多反应器多线程模式的伪代码如下:
参考资料:
如果您需要交流或文章错误,请直接留言。此外,我想喜欢,收集和关注,我将继续更新各种Java学习博客!