Multithreading 为什么我要选择基于线程/进程的方法而不是异步web服务器

Multithreading 为什么我要选择基于线程/进程的方法而不是异步web服务器,multithreading,asynchronous,webserver,multiprocessing,Multithreading,Asynchronous,Webserver,Multiprocessing,随着我对web服务器软件做了更多的研究,我开始质疑Apache的基于线程/进程的方法是否是解决方案,而Nginx a Lighttpd等服务器提供的异步请求处理与此相反,后者在负载较重时往往扩展得更好 我知道后两者和Apache之间还有很多其他的区别。我的问题是,在什么情况下,我会选择基于线程/进程的方法而不是异步处理 是否有我不能与异步方法一起使用的功能/技术(或者功能不好/不好) 什么情况会导致异步方法的性能比基于线程/进程的方法差?这些病例是常见的还是罕见的,差别有多大 在比较这两者时,我

随着我对web服务器软件做了更多的研究,我开始质疑Apache的基于线程/进程的方法是否是解决方案,而Nginx a Lighttpd等服务器提供的异步请求处理与此相反,后者在负载较重时往往扩展得更好

我知道后两者和Apache之间还有很多其他的区别。我的问题是,在什么情况下,我会选择基于线程/进程的方法而不是异步处理

  • 是否有我不能与异步方法一起使用的功能/技术(或者功能不好/不好)

  • 什么情况会导致异步方法的性能比基于线程/进程的方法差?这些病例是常见的还是罕见的,差别有多大

  • 在比较这两者时,我还应该考虑其他因素吗?请记住,我主要关注的是基于线程/进程的方法与异步方法,而不是碰巧使用其中一种方法的任何特定服务器软件。这些问题可能是管理/调试困难、安全问题等


  • 与线程和异步模型相比,进程在安全性和可靠性方面有几个优势。大多数网站不需要这些特殊的优势,但有时它们是不可或缺的

  • 安全性:您可以作为低权限用户在沙箱中运行工作进程,并且每个工作进程只能处理一个请求。这缓解了某些类型的安全漏洞:即使攻击者接管了您的整个工作进程,只要您根据请求元数据对其进行严格的沙盒处理(即,它没有对所有数据的写访问权),那么它也不会损害系统稳定性或影响对请求的响应
  • 安全性#2:有时您需要对不受信任的代码进行沙箱处理,或者在不同的代码或不同的请求之间强制隔离,唯一的方法是使用单独的一次性流程。(考虑运行用户提供的代码。)
  • 可靠性:如果您定期(或针对每个请求)拆卸和更换工作进程,内存泄漏和内存损坏的严重性将大大降低
  • 在单独的进程中处理用户请求所花费的CPU时间、磁盘和网络配额等很容易实施硬限制。即使请求处理代码进入无限循环,主进程(或操作系统)也可以强制执行超时

  • 这很古老,但值得回答。让我们首先说明每个模型是如何工作的

    在threaded中,有一个请求进入处理程序,处理程序生成一个新的OS线程来处理该请求,该请求的所有工作都在该线程中进行,直到发送响应并结束该线程。此模型支持的并发请求数量与您的服务器可以生成的线程数量相同(但线程可能有点重)

    当执行异步时,请求进入处理程序,但不是创建线程来处理它,而是将连接添加到事件循环中。事件循环侦听连接上的数据/状态更改,并在每次发生“某事”时触发回调。将连接添加到事件循环后,处理程序立即侦听要添加的新连接。这允许您同时拥有多个(有时是100K)并发连接

    是否有我不能与异步方法一起使用的功能/技术(或者功能不好/不好)

    是的,当你做数字运算的时候。异步(或“事件化”)系统的体系结构是这样的:它擅长于传递数据,而不是处理数据。它可以处理数千个并发操作,但因为它只在一个OS线程上运行,所以它所触发的回调需要尽可能少地执行,以获得最大的吞吐量。这是因为,如果您的一个回调执行了耗时5秒的数字处理,则整个服务器将冻结5秒,直到该操作完成。其思想是获取数据,将其发送到它要去的地方(数据库、API等),并发送一个响应,所有这些都需要最少的处理

    异步适用于网络I/O:在多个源/目的地之间传递数据(以及用户界面,但这超出了本文的范围)

    什么情况会导致异步方法的性能比基于线程/进程的方法差?这些病例是常见的还是罕见的,差别有多大

    请参见上面的内容,但任何时候当您做的CPU工作超过网络I/O时,都应该切换到线程模型。不过,也有一些架构解决方案……例如,您可以拥有一个异步应用程序,在它需要执行实际工作的任何时候,它都会将作业发送到工作队列。然而,如果每个请求都需要CPU处理,那么这种体系结构就太过分了,您也可以使用线程服务器

    在比较这两者时,我还应该考虑其他因素吗?请记住,我主要关注的是基于线程/进程的方法与异步方法,而不是碰巧使用其中一种方法的任何特定服务器软件。这些问题可能是管理/调试困难、安全问题等

    异步编程通常比线程编程更复杂。这就是说,如果您不自己编程(即在nginx和apache之间进行选择),那么我通常建议您使用异步(nginx),因为这样通常可以从服务器中挤出更多的资源。我一直赞成在堆栈中使用尽可能多的异步

    这就是说,如果您正在编写一个应用程序,并试图决定是使用线程模型还是异步模型,那么您必须考虑开发人员的时间。除非您使用的语言在事件循环(如scheme)上有绿色线程,否则您可能会对qui感到毛骨悚然