为什么会出现异步Web服务器?

大家好。联系弗拉迪斯拉夫·罗丹(Vladislav Rodin)。目前,我是OTUS高负载架构师课程的负责人,并且还教授软件架构课程。

如您所见,除了教学之外,我还一直在写博客版权材料OTUSHabré,今天的文章我想与《 Linux Administrator》课程的开始相吻合,该课程现已开放。





介绍


为什么Web应用程序会变慢并且不承担负载?最早遇到此类问题并在某些系统上进行研究的开发人员得出的令人失望的结论是,仅优化业务逻辑是不够的。这个问题的答案在较低的层次上-在操作系统的层次上。为了使您的应用程序能够承受负载,有必要以使其在此级别有效工作的方式来审查其体系结构概念。这导致了异步Web服务器的出现。

不幸的是,我找不到一种可以使我立即恢复Web服务器发展中所有因果关系的材料。所以写这篇文章的想法浮出水面,我希望它将成为这样的材料。

Linux OS功能


在讨论Web服务器的模型之前,我先回顾一下Linux中进程和线程的某些功能。在分析上述模型的优缺点时,我们将需要此功能。

上下文切换


任何可能一次只能在一个处理器内核上执行一个程序的用户都将问:“为什么一次只能在我的4核处理器上启动20个程序?”。

实际上,这是由于发生了抢先式多任务处理操作系统会分配一定的时间量(〜50μs),并在这段时间内将程序放在内核上执行。时间耗尽后,上下文切换中断切换也就是说,操作系统只是简单地放入下一个程序来执行。由于切换频繁发生,因此我们给所有程序一个印象。注意高开关频率,这对于后续演示很重要。

上面提到了上下文切换。它包括什么?切换上下文时,必须保存处理器寄存器,以清除其指令流水线,以保存分配给进程的内存区域。通常,该操作非常昂贵。大约需要0.5μs的时间,而简单代码行的执行则需要1 ns的时间。此外,随着每个处理器内核的处理数量的增加,上下文切换的开销将增加。

Web服务器模型


当前,存在以下Web服务器模型:

  • 工人
  • 前叉
  • 异步
  • 合并的


让我们分别讨论它们。

工人和前叉


从历史上看,有了这些模型,一切就开始了。本质很简单:一个客户来到我们这里,我们为他选择一个单独的处理程序,该处理程序从头到尾处理传入的客户。处理程序可以是进程(prefork)或线程(worker)。这种Web服务器的一个示例是众所周知的Apache。

我会立即进行预订:为每个客户创建一个新的处理程序非常昂贵。首先,在核心数量恒定的情况下,处理器数量的增加导致延迟的增加(由于上下文切换)。其次,所需的内存量随客户端的增加呈线性增长,因为即使您使用内存共享线程,每个线程也都有自己的堆栈。因此,限制了同时处理的客户端数量。池的大小取决于处理器内核的数量。使用垂直缩放方法可以解决该问题。

这种服务器的另一个基本缺点是资源的非最佳使用。进程(或线程)在大多数时间都是空闲的想象一下以下情况:在客户端处理期间,有必要从硬盘驱动器中获取一些数据,向数据库发出请求,或向网络中写入一些内容。由于在Linux中从硬盘读取是一项阻塞操作,因此进程(或线程)将挂起以等待响应,但仍将参与处理器时间的分配。

工人VS前叉


工人和前叉有很多基本差异。流在内存中更经济一些,因为它们共享它们。出于相同的原因,它们之间的上下文切换比进程之间的上下文切换更容易。但是,对于工作程序,由于线程必须同步,因此代码变为多线程。结果,我们得到了多线程代码的所有“魅力”:编写,读取,测试和调试它变得更加困难。

异步模型


因此,由于池大小有限,worker和prefork不允许同时处理大量客户端,并且由于上下文切换和阻塞系统调用,也无法最佳地使用资源。如您所见,问题是多线程和繁重的OS调度程序。这导致了以下想法:让我们仅在一个线程中处理客户端,但让其以100%的速度加载。

这样的服务器基于事件循环和反应器模板(事件机器)。客户端代码,启动I / O操作,注册一个回调在优先级队列中(优先级是准备时间)。事件循环轮询等待I / O的描述符,然后更新优先级(如果有)。另外,事件循环将事件从优先级队列中拉出,导致回调将控制权最终返回到事件循环。

该模型允许您处理大量客户端,从而避免了切换上下文的开销。该模型不是完美的,并且具有几个缺点。首先,由于只使用一个进程,因此只消耗了一个处理器核心。使用组合模型对此进行处理,下面将对此进行讨论。其次,通过此过程将客户联系起来。该代码需要仔细编写。内存泄漏,错误导致所有客户端立即崩溃的事实。此外,此过程不应被任何东西阻止,回调不应包含解决一些困难的任务,因为所有客户端都将被阻止。第三,异步代码要复杂得多有必要注册一个额外的回调,使数据不会出现,以解决如何正确分支的问题,等等。

组合模型


该模型用于实际服务器中。该模型有一个进程池,每个进程都有一个线程池,每个线程又使用基于异步输入输出的处理模型。Nginx提出了一个组合模型。

结论


因此,转向操作系统的基础知识,我们研究了Apache和Nginx中使用的Web服务器模型之间的概念差异。它们每个都有其优点和缺点,因此它们的组合经常在生产中使用。

异步处理的概念进一步发展了:在语言平台级别上,出现了绿色线程/纤维/ goroutines概念,使您可以将输入和输出的异步“隐藏在后台”,使开发人员对漂亮的同步代码感到满意。但是,此概念值得单独撰写。



了解有关该课程的更多信息。



All Articles