服务器模型——从单线程阻塞到多线程非阻塞(下)

原创 2018年01月03日 00:00:00

前言的前言

    服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: 
* 单线程/多线程阻塞I/O模型 
* 单线程非阻塞I/O模型 
* 多线程非阻塞I/O模型,Reactor及其改进

前言

    这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。

    对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。

    对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。

多线程非阻塞I/O模型

    单线程非阻塞I/O模型已经大大提高了机器的效率,而在多核的机器上可以通过多线程继续提高机器效率。最朴实、最自然的做法就是将客户端连接按组分配给若干线程,每个线程负责处理对应组内的连接。如图所示,有4个客户端访问服务器,服务器将套接字1和套接字2交由线程1管理,而线程2则管理套接字3和套接字4,通过事件检测及非阻塞读写就可以让每个线程都能高效处理。

caNYYfYLhoHM5yGqrdHtrRy2rao6ny7swq8nLYMVYaYE1fkAdmtRLicLiavicyLgLKW4EoDTAvqGVXOnWWicBnSCsw

    最经典的多线程非阻塞I/O模型方式是Reactor模式。首先看单线程下的Reactor,Reactor将服务器端的整个处理过程分成若干个事件,例如分为接收事件、读事件、写事件、执行事件等。Reactor通过事件检测机制将这些事件分发给不同处理器去处理。如图所示,若干客户端连接访问服务器端,Reactor负责检测各种事件并分发到处理器,这些处理器包括接收连接的accept处理器、读数据的read处理器、写数据的write处理器以及执行逻辑的process处理器。在整个过程中只要有待处理的事件存在,即可以让Reactor线程不断往下执行,而不会阻塞在某处,所以处理效率很高。

    基于单线程Reactor模型,根据实际使用场景,把它改进成多线程模式。常见的有两种方式:一种是在耗时的process处理器中引入多线程,如使用线程池;另一种是直接使用多个Reactor实例,每个Reactor实例对应一个线程。

caNYYfYLhoHM5yGqrdHtrRy2rao6ny7s4UMoagevsicp4KV1b0KPdDB9nGSicicclNviaiatvQ4dumgLDy4ib6V35icXQ

    Reactor模式的一种改进方式如图所示。其整体结构基本上与单线程的Reactor类似,只是引入了一个线程池。由于对连接的接收、对数据的读取和对数据的写入等操作基本上都耗时较少,因此把它们都放到Reactor线程中处理。然而,对于逻辑处理可能比较耗时的工作,可以在process处理器中引入线程池,process处理器自己不执行任务,而是交给线程池,从而在Reactor线程中避免了耗时的操作。将耗时的操作转移到线程池中后,尽管Reactor只有一个线程,它也能保证Reactor的高效。

caNYYfYLhoHM5yGqrdHtrRy2rao6ny7sYKSC0Wia06Lp1nUxM1mA07gLCGw3E9pbm2SXiamDjXFUTyNxrBkUic9XQ

    Reactor模式的另一种改进方式如图所示。其中有多个Reactor实例,每个Reactor实例对应一个线程。因为接收事件是相对于服务器端而言的,所以客户端的连接接收工作统一由一个accept处理器负责,accept处理器会将接收的客户端连接均匀分配给所有Reactor实例,每个Reactor实例负责处理分配到该Reactor上的客户端连接,包括连接的读数据、写数据和逻辑处理。这就是多Reactor实例的原理。

    多线程非阻塞I/O模式让服务器端处理能力得到很大提高,它充分利用机器的CPU,适合用于处理高并发的场景,但它也让程序更复杂,更容易出现问题。

caNYYfYLhoHM5yGqrdHtrRy2rao6ny7sibPkob6jtJzd4sxKR309QfXTnic4ssDjIJJRmeHv5Kq58maSm0lqZvog


服务器模型——从单线程阻塞到多线程非阻塞(上)

服务器模型——从单线程阻塞到多线程非阻塞(中)

=============广告时间===============

公众号的菜单已分为“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以购买。感谢各位朋友。

为什么写《Tomcat内核设计剖析》

=========================


版权声明:本文为博主原创文章,未经博主允许不得转载。

如何理解Node.js中 单线程、非阻塞IO、事件驱动

Node.js中单线程就相当于火车站售票厅只开一个售票窗口,那么所有的人都要通过这个窗口去买票,如果说这些人不排队都争抢这个窗口,可想而知,每一个人想买到票很难,还有一个就是我们经常做公交车,公交车师...
  • qq_15267341
  • qq_15267341
  • 2016年09月15日 20:48
  • 3673

服务器模型——从单线程阻塞到多线程非阻塞(上)

前言的前言    服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分:单线程/多线程阻塞I/O模型单线程非阻塞I/O模型多线程非阻塞I/O模型,Reactor及其...
  • s3FRH3JyN6yymHmT11
  • s3FRH3JyN6yymHmT11
  • 2017年12月21日 00:00
  • 108

服务器模型——从单线程阻塞到多线程非阻塞(下)

前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2018年01月04日 09:14
  • 491

最全服务器模型详解——从单线程阻塞到多线程非阻塞

前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分:单线程/多线程阻塞I/O模型单线程非阻塞I/O模型多线程非阻塞I/O模型,Reactor及其改进前...
  • a26r2kF967hGAi
  • a26r2kF967hGAi
  • 2018年01月05日 00:00
  • 109

基于HTTP、NIO、单线程实现浏览器并发非阻塞访问服务器文件

  • 2017年04月05日 11:46
  • 11.23MB
  • 下载

单线程、事件驱动、异步非阻塞的nginx

nginx(发音"engine x")是俄罗斯软件工程师Igor Sysoev开发的免费开源web服务器软件。nginx于2004年发布,聚焦于高性能,高并发和低内存消耗问题。并且具有多种web服务器...
  • yangbutao
  • yangbutao
  • 2013年01月15日 14:41
  • 14319

服务器模型——从单线程阻塞到多线程非阻塞(中)

前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2017年12月26日 10:34
  • 995

服务器模型——从单线程阻塞到多线程非阻塞(上)

前言的前言服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型,R...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2017年12月22日 09:21
  • 1055

关于对Node.js的“单线程非阻塞异步I/O”特点的个人理解

关于Node.js的运行机制的个人理解: (1)当发起一个异步(非阻塞或阻塞)调用时,就会封装异步调用的请求对象。 (2)封装完后的对象就会放入线程池内等待执行。 (3)当线程池查询有空时就会执行请求...
  • Cyan1614
  • Cyan1614
  • 2017年06月17日 17:28
  • 292

python的单线程异步非阻塞框架karlooper

karlooper是一款单线程异步非阻塞的web framework; 其性能堪比tornado; 使用简单,容易上手,创建一个index.py,代码如下: # -*-coding:utf-8-*-...
  • KarlDoenitz
  • KarlDoenitz
  • 2016年07月01日 23:35
  • 923
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:服务器模型——从单线程阻塞到多线程非阻塞(下)
举报原因:
原因补充:

(最多只允许输入30个字)