Reactor 与 Proactor 模型是近几年技术领域频频提到的两个设计模式,那么,究竟什么是 Reator,什么又是 Proactor,他们之间有什么异同呢? 本文就来详细介绍一下。
Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。
这是05年的老文章,网上应该有人早就翻译过了,我翻译它仅仅为了学习Reactor/Proactor两种TCP服务器设计模式,顺便作翻译练习。
同步阻塞模式。在JDK1.4以前,使用Java建立网络连接时,只能采用BIO方式,在服务器端启动一个ServerSocket,然后使用accept等待客户端请求,对于每一个请求,使用一个线程来进行处理用户请求。线程的大部分时间都在等待请求的到来和IO操作,利用率很低。而且线程的开销比较大,数量有限,因此服务器同时能处理的连接数也很低。
本文将介绍基于进程/线程模型,服务器如何处理请求。值得说明的是,具体选择线程还是进程,更多是与平台及编程语言相关。
上面文章中,我们提到不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成,所以就演变出来两种高性能的io的设计模式,分别是Reactor(同步IO)和Proactor(异步IO)。
Proactor是常见的网络AIO模型。和Reactor的区别在于同步/异步。问题在于windows没有好的NIO,而Linux又没动力实现AIO,所以Reactor占多数。
随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力。本文旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱。 2、关于作者 陈彩华(caison):主要从事服务端开发、需求分析、系统设计、优化重构工作,主要开发语言是 Java。 3、线程模型 上篇《高性能网络编程(五):一文读懂高性能网络编程中的I/O模型》介绍完服务器如何基于 I/O 模型管理连接,获取输入数据,下面将介绍基于进程/线程模型,服务器如何处理请求。 值得说明的是,具体选择线程还是进程,更多是与平台及编程语言相关。 例如 C 语言使用线程和进程都可以(例如 Nginx 使用进程,Memcached 使用线程),Java 语言一般使用线程(例如 Netty),为了描述方便,下面都使用线程来进行描述。 4、线程模型1:传统阻塞 I/O 服务模型
reactor是关心就绪事件,比如可读了,就通知你,就像epoll_wait 。proactor关心的是完成比如读完了,就通知你。
本文介绍了多线程和并发的基本概念,以及常见的多线程服务器方案,如基于循环的迭代服务器、基于协程的并发服务器、基于事件驱动的非阻塞服务器和异步I/O服务器。作者还列举了一些常见的服务器应用场景,并给出了muduo库和Boost.Asio库的示例代码。
ACE是一个很成熟的中间件产品,为自适应通讯环境,但它过于宏大,一堆的设计模式,架构是一层又一层,对初学者来说,有点困难。
Boost ASIO proactor 浅析 前情提要: Boost asio 的socket的异步非阻塞模式才有的是proactor模式,当IO操作介绍后回调相应的处理函数。ASIO在Linux平台下的实现基于epoll,但是epoll只支持reactor模式,ASIO通过封装在epoll上实现了proactor。提到ASIO proactor,ASIO中的所有异步操作都是基于io_service实现的,io_service是ASIO中的任务队列,并且他负责调用epoll_wait等待IO事件到来,对io
(2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。
别小看这两个东西,特别是 Reactor 模式,市面上常见的开源软件很多都采用了这个方案,比如 Redis、Nginx、Netty 等等,所以学好这个模式设计的思想,不仅有助于我们理解很多开源软件,而且也能在面试时吹逼。
服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型。 (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。 (3)IO多路复用(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型
文章比较长,需要一些耐心才能看完 并发模型简介 并发:一个人同一时间应对多件事的能力 并行:一个人同一时间处理多件事的能力(显然一个人同一事件不能处理多件事,单核CPU不具备并行能力) 可以理解为并行是并发的一种特殊情况 并发模型的核心是为了提高提高CPU利用率,提高服务器应对大量请求,海量数据处理的能力,单核CPU性能已经难以发展,各大厂商都在通过增加CPU个数来达到硬件处理能力的提高(摩尔定律),随之而来在编程语言方面衍生出各个模型(其实就是处理问题的思路)用来压榨硬件的性能,以使自己的系统并发能力得到
架构师是一个很神圣的职业,充满玄学之道,并不是每一个人都能够成为架构师,架构师需要具备很强的技术思维和业务思维以及产品思维,当然也很考验计算机功底,操作系统也是计算机功底的一部分。
上一篇文章讲解了I/O模型的一些基本概念,包括同步与异步,阻塞与非阻塞,同步IO与异步IO,阻塞IO与非阻塞IO。这次一起来了解一下现有的几种IO模型,以及高效IO的两种设计模式,也都是属于IO模型的基础知识。
NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。 那么NIO的本质是什么样的呢?它是怎样与事件模型结合来解放线程、提高系统吞吐的呢? 本文会从传统的阻塞I/O和线程池模型面临的问题讲起,然后对比几种常见I/O模型,一步步分析NIO怎么利用事件模型处理I/O,解决线程池瓶颈处理海量连接,包括利用面向事件的方式编写服务端/客户端程序。
作者:美团点评技术团队 链接:https://zhuanlan.zhihu.com/p/23488863 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
导语 | 本文介绍了部分高性能网络方案,包括RDMA、HARP、io_uring等。从技术原理、落地可行性等方面,简要地做出分析,希望能对此方面感兴趣的开发者提供一些经验和帮助。 一、背景 业务中经常会有这样的场景: 随着网卡速率的提升(10G/25G/100G),以及部分业务对低延迟的极致追求(1ms/50us),目前的内核协议栈由于协议复杂、流程复杂、设计陈旧等因素,已经逐渐成为业务瓶颈。 业界已经有部分RDMA、DPDK的实践,但是对于大多数开发者而言,依然比较陌生。 那么这些方案各自的场景究竟怎样?
在高性能的I/O设计中,有两个著名的模型:Reactor模型和Proactor模型,其中Reactor模型用于同步I/O,而Proactor模型运用于异步I/O操作。
两种高效事件处理模式&并发模式 来源如下,侵删。 游双-《Linux高性能服务器编程》 本来想做个笔记的,但是发现这块内容书中很多都感觉是有用的,所以很大篇幅的搬了过来,其中加入了我的理解,并有重点标注。 服务器编程框架 服务器程序种类繁多,但是基本框架都一样,不同之处在于逻辑处理。 下图所示,服务器基本框架。该图既能用来描述一台服务器,也能用来描述一个服务器机群。 📷 各模块概念 模块 单个服务器框架 服务器机群 I/O逻辑单元 处理客户连接,读写网络数据 作为接入服务器,实现负载聚
虽然市面上已经有很多成熟的网络库,但是编写一个自己的网络库依然让我获益匪浅,这篇文章主要包含:
在web体系中,相比线程连接架构设计而言,事件驱动设计更满足我们实现一个高性能IO的web服务,这点在高性能IO编程一文已经有讲述.对此,我们接下来将要展开如何去设计一个基于IO事件驱动架构的web服务,目前有Reactor同步多路复用模式以及Proactor异步多路复用模式两种方案,通过后面文章的分析,我们可以了解到这两种方案的设计思路,具体实现原理以及这两种模式各自的优势以及不足.
Reactor模式的核心思想是:当有IO事件发生时,通过一个统一的事件循环来分发和处理这些事件。这个事件循环通常是一个无限循环,在每一次循环中,它会阻塞等待IO事件发生,当事件发生时,它会调用相应的处理函数来处理这个事件。
本来想对netty的源码进行学习和探究,但是在写netty之前许多底层的知识和原理性的东西理解清楚,那么对学习网络通讯框架的效果则会事半功倍。
- IO 模型的基本概念 - 同步阻塞IO(Blocking IO):即传统的IO模型。 同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。 多路复用IO(IO Multiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型(Redis单线程为什么速度还那么快,
1)获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3); 2)构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4); 3)返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)。
http://blog.csdn.net/zs634134578/article/details/19806429
②同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库。
DMA : direct memory access 直接内存拷贝( 不使用CPU )
网络I/O,可以理解为网络上的数据流。通常我们会基于socket与远端建立一条TCP或者UDP通道,然后进行读写。单个socket时,使用一个线程即可高效处理;然而如果是10K个socket连接,或者更多,我们如何做到高性能处理?
大家好,我是易安!今天我们谈一谈架构设计中的高性能架构涉及到的底层思想。本文分为缓存架构,单服务器高性能模型,集群下的高性能模型三个部分,内容很干,希望你仔细阅读。
我的理解中PHP-FPM使用的是这个 , 单Reactor 多进程 , 主进程Reactor接收连接请求 , 子进程处理每个连接
上篇文章,我们介绍了Java IO框架的演变,其实编程语言的IO实现是依赖于底层的操作系统,如果OS内核不支持,那么语言层面也无能为力。任何一个跨平台的编程语言,一定是能够在不同操作系统之间选择使用最优的IO模型,那么不同平台的io策略都有哪些实现呢?本篇文章我们就来了解一下。
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。
导语 | 在需要高性能、节省资源的场景下,比如海量的连接、很高的并发,我们发现Go开始变得吃力,不但内存开销大,而且还会有频繁的goroutine调度。GC时间也变得越来越长,甚至还会把系统搞挂。这时,我们就可以考虑用Go构建经典的Reactor网络模型,来应对这种场景。 一、常见的服务端网络编程模型 在具体讲Reactor网络库的实现前,我们先快速回顾下常见的服务端网络编程模型。 服务端网络编程主要解决两个问题,一个是服务端如何管理连接,特别是海量连接、高并发连接(经典的c10k/c100k问题),二是服
Reactor是基于同步I/O的, 他要求主线程(I/O处理单元)只负责监听文件描述符上是否有事件发生, 有的话就立刻将该事件通知给工作线程(逻辑单元). 初次之外, 主线程不做任何其他实质性的工作. 读写数据, 接受新的连接, 以及处理客户请求均在工作线程中完成.
Windows 10 系统下,IPython 解释器内执行某些程序,会导致出现类似如下报错:
最近阅读了一本架构方面的入门图书叫《从零开始学架构:照着做,你也能成为架构师》,部分内容比较不错,先做书摘总结,以便加深印象与未来回顾学习。
上一篇文章中,我们介绍了编程思想中的 Reactor 与 Proactor 两种设计模式: 程序设计中的两大经典模式 — Reactor & Proactor
ASIO是一个久经迭代的库, 所以版本比较多, 不同版本的差异也比较大, 在开始具体的讲述前, 我们先来看一下ASIO的版本情况, 也方便大家知道我们所选用的ASIO版本, 以及它与最新的版本的差异所在.
最近看到篇好文章《IO多路复用》,记得早期学习时,也去探索过select、poll、epoll的区别,但后来也是没有及时记录总结,也忘记了,学习似乎就是在记忆与忘记中徘徊,最后在心中留下的火种,是熄灭还是燎原就看记忆与忘记间的博弈
setsockopt可以设置各类套接字的一些配置属性。 如: SO_REUSEADDR ——防止服务器重启受阻 SO_REUSEPORT – 开启端口重用,允许多个套接字bind/listen同一个端口 SO_KEEPALIVE – 心跳机制 TCP_NODELAY – 取消Nagle(取消小包合并) CLOEXEC:fork之后写时复制,因此在未写时与父进程共享文件(指向相同)。但如果子进程此时采用exec替换进程,需要在替换之前关闭无用的fd。如果相应的fd非常多,这会很难做到。因此指
很多年以前,网易推了一个tcp流量复制工具叫tcpcopy。2013年07月我入职新公司,大概10月份接触到tcpcopy,为tcpcopy修了两个bug,一个是由于公司内网的IP tunnel的问题tcpcopy无法正常工作;另一个是一个严重的性能bug。两个bug都用邮件方式向原作者反馈了,尤其第二个bug原作者在博客上发文感谢。在接下来的二次开发中,由于没办法看懂tcpcopy的tcp会话部分的代码,当时建议作者按照tcp的11个状态写成状态机,作者拒绝了。于是,我根据当时的业务情况重写了一个新的TCPCOPY叫TCPGO。技术原理和tcpcopy是一样的,但tcp会话部分写成了标准 的11个tcp状态的状态机(见源代码中的tcpsession类,漂亮的运行在应用空间而不是内核态的精简的tcp状态机)。另部署方式很不一样,要简单很多。为了开发效率,开发语言用了C++,用了boost库还加了lua帮助写业务代码。
最近在读一本<<软件架构设计:大型网站技术架构与业务融合之道>>,它就像是把你平时一点点积累的知识有条理且有深度的整合。一步一步的将读者断断续续的知识接起来。以下文章是记录书本中的一些知识并加以拓展。
Go与C/C++消耗的CPU差距不大,但由于Go是垃圾回收型语言,耗费的内存会多一些。 拿Go与同为垃圾回收型语言的Java简单比较一下。
服务器并发场景是在程序IO密集型有优势。因为IO操作速度远没有CPU的计算速度快。程序阻塞IO将浪费大量CPU时间。程序计算密集型的,并发编程反而没有优势。
领取专属 10元无门槛券
手把手带您无忧上云