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

前言的前言

服务器模型涉及到线程模式和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模型是最简单的一种服务器模型,几乎全部程序员在刚开始接触网络编程时都从这个简单的模型开始。这种模型只能同时处理一个客户端访问,而且在I/O操做上是阻塞的,线程会一直在等待,而不会作其余事情。对于多个客户端访问,必需要等到前一个客户端访问结束才能进行下一个访问的处理,请求一个一个排队,只提供一问一答服务。多线程

首先,服务器必须初始化一个套接字服务器,并绑定某个端口号并使之监听客户端的访问。接着,客户端1调用服务器的服务,服务器接收到请求后对其进行处理,处理完后写数据回客户端1,整个过程都是在一个线程里面完成的。最后,处理客户端2的请求并写数据回客户端2,期间就算客户端2在服务器处理完客户端1以前就进行请求,也要等服务器对客户端1响应完后才会对客户端2进行响应处理。并发

这种模型的特色在于单线程和阻塞I/O。单线程即服务器端只有一个线程处理客户端的全部请求,客户端链接与服务器端的处理线程比是n:1,它没法同时处理多个链接,只能串行处理链接。而阻塞I/O是指服务器在读写数据时是阻塞的,读取客户端数据时要等待客户端发送数据而且把操做系统内核复制到用户进程中,这时才解除阻塞状态。写数据回客户端时要等待用户进程将数据写入内核并发送到客户端后才解除阻塞状态。这种阻塞给网络编程带来了一个问题,服务器必需要等到客户端成功接收才能继续往下处理另一个客户端的请求,在此期间线程将没法响应任何客户端请求。机器学习

该模型的特色:它是最简单的服务器模型,整个运行过程都只有一个线程,只能支持同时处理一个客户端的请求(若是有多个客户端访问,就必须排队等待),服务器系统资源消耗较小,但并发能力低,容错能力差。分布式

多线程阻塞I/O模型

针对单线程阻塞I/O模型的缺点,咱们可使用多线程对其进行改进,使之能并发地对多个客户端同时进行响应。多线程模型的核心就是利用多线程机制为每一个客户端分配一个线程。服务器端开始监听客户端的访问,假若有两个客户端发送请求过来,服务器端在接收到客户端请求后分别建立两个线程对它们进行处理,每条线程负责一个客户端链接,直到响应完成。期间两个线程并发地为各自对应的客户端处理请求,包括读取客户端数据、处理客户端数据、写数据回客户端等操做。性能

这种模型的I/O操做也是阻塞的,由于每一个线程执行到读取或写入操做时都将进入阻塞状态,直到读取到客户端的数据或数据成功写入客户端后才解除阻塞状态。尽管I/O操做阻塞,但这种模式比单线程处理的性能明显高了,它不用等到第一个请求处理完才处理第二个,而是并发地处理客户端请求,客户端链接与服务器端处理线程的比例是1:1。学习

多线程阻塞I/O模型的特色:支持对多个客户端并发响应,处理能力获得大幅提升,有较大的并发量,但服务器系统资源消耗量较大,并且多线程之间会产生线程切换成本,同时拥有较复杂的结构。

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

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

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

为何写《Tomcat内核设计剖析》

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

欢迎关注:

这里写图片描述
相关文章
相关标签/搜索