【发布时间】:2018-09-12 22:45:20
【问题描述】:
我正在为我们的新后端项目考虑一些框架/编程方法。它涉及聚合下游服务的 BackendForFrontend 实现。为简单起见,以下是它所经历的步骤:
- 请求进入网络服务器
- 网络服务器发出下游请求
- 下游请求返回结果
- 网络服务器返回请求
事件驱动编程比“常规的”线程每个请求处理更好吗?一些网站试图解释,通常归结为这样的:
第二种解决方案是非阻塞调用。调用者不等待答案,而是继续执行,但提供了一个回调,一旦数据到达就会执行。
我不明白的是:我们需要一个线程/处理程序来等待这些数据,对吧?事件处理程序可以继续,这很好,但我们仍然需要(在此示例中)每个请求的线程/处理程序来等待每个下游请求,对吧?
考虑这个例子:下游请求需要 n 秒才能返回。在这 n 秒内,有 r 个请求进来。在每个请求的线程中,我们需要 r 个线程:每个请求一个。经过 n 秒后,第一个线程完成处理并可用于新请求。
在实现事件驱动设计时,我们需要 r+1 个线程:一个事件循环和 r 个处理程序。每个处理程序接受一个请求,执行它,并在完成后调用回调。
那么这对改善有什么好处呢?
【问题讨论】:
-
我刚刚想到的:如果我们有一个可以在同一个线程上处理多个请求的处理程序,那么好处是显而易见的:我们只需要一个(或几个冗余)处理程序,从而大大减少了数量所需的线程数。但这真的不可能,对吧?
-
为什么不呢? “处理程序”只是一个数据结构,它记住上游和下游每个连接(套接字号、地址、cookie 等)的状态并维护它们之间的关联,加上一些知道如何处理下一个输入的代码,实际上, 在您的状态机上“转动曲柄”。每个连接都有自己独立的数据结构/当前状态。在单个线程中可以处理多少个请求没有硬性限制。
-
你能详细说明一下吗?这样的实现怎么叫?我尝试对此进行研究,但找不到任何东西,但也许我的关键字(“同一线程上的多个 HTTP 请求”)不正确
-
据我了解,您总是需要一个线程池来执行并行请求,因为您必须始终以同步方式执行请求。是的,您可以围绕此构建一个异步 API,但实际上执行请求需要一个等待线程(再次,据我了解)
-
没有。套接字接收(当数据已经可用时)只是将字节从内核缓冲区复制到用户空间缓冲区。发送是相反的:从用户空间复制到内核(假设内核缓冲区中有空间)。因此,这些操作是“同步的”,因为当它们正在进行时,您的线程中没有发生任何其他事情,但它们几乎是瞬间完成的。
select、poll和类似机制允许您等待多个套接字中的任何一个变为“可读”或“可写”。
标签: multithreading webserver event-driven event-driven-design