事件驱动编程如何帮助仅执行 IO 的 Web 服务器?

2023-12-08

我正在考虑为我们的新后端项目使用一些框架/编程方法。它涉及 BackendForFrontend 实现,聚合下游服务。为简单起见,以下是它所经历的步骤:

  1. 请求进入网络服务器
  2. Web服务器发出下游请求
  3. 下游请求返回结果
  4. Web服务器返回请求

事件驱动编程如何比“常规”每个请求线程处理更好?有些网站试图解释,通常可以归结为这样的内容:

第二种解决方案是非阻塞调用。调用者没有等待答案,而是继续执行,但提供了一个回调,一旦数据到达就会执行该回调。

我不明白的是:我们需要一个线程/处理程序来等待这些数据,对吗?事件处理程序可以继续很好,但我们仍然需要(在本例中)每个请求有一个线程/处理程序来等待每个下游请求,对吗?

考虑这个例子:下游请求需要 n 秒才能返回。在这n秒内,有r个请求进来。在每个请求的线程中,我们需要r个线程:每个请求一个。经过 n 秒后,第一个线程完成处理并可用于新请求。

在实现事件驱动设计时,我们需要 r+1 个线程:一个事件循环和 r 个处理程序。每个处理程序接受一个请求,执行它,并在完成后调用回调。

那么这如何改善情况呢?


我不明白的是:我们需要一个线程/处理程序来等待这些数据, 正确的?

并不真地。 NIO 背后的想法是任何线程都不会被阻塞。

这很有趣,因为操作系统已经以非阻塞方式工作。我们的编程语言是以阻塞方式建模的。

举个例子,假设您有一台带有单个 CPU 的计算机。您执行的任何 I/O 操作都会比 CPU 慢几个数量级,对吧?假设你想读取一个文件。你认为CPU会呆在那里,闲置,什么也不做,而磁盘头会去获取一些字节并将它们放入磁盘缓冲区吗?很明显不是。操作系统将注册一个中断(即回调),并同时将宝贵的 CPU 用于其他事情。当磁头成功读取几个字节并使其可供使用时,就会触发中断,操作系统会关注该中断,恢复之前的进程块并分配一些CPU时间来处理可用数据。

因此,在这种情况下,CPU 就像应用程序中的一个线程。它永远不会被阻止。它总是在做一些CPU密集型的事情。

NIO 编程背后的思想是相同的。在您公开的情况下,假设您的 HTTP 服务器有一个线程。当您收到来自客户端的请求时,您需要发出上游请求(代表 I/O)。因此,NIO 框架在这里要做的就是发出请求并在响应可用时注册回调。

之后,您宝贵的单线程立即被释放以处理另一个请求,该请求将注册另一个回调,依此类推。

当回调解析时,它将自动安排由您的单线程处理。

因此,该线程作为一个事件循环工作,您应该在其中仅调度 CPU 密集型内容。每次需要执行 I/O 时,都会以非阻塞方式完成,并且当 I/O 完成时,会将一些 CPU 绑定的回调放入事件循环中以处理响应。

这是一个强大的概念,因为使用非常少量的线程就可以处理数千个请求,因此可以更轻松地扩展。用更少的钱做更多的事。

此功能是其主要卖点之一Node.js以及为什么即使使用单线程也可以用来开发后端应用程序。

同样,这也是像这样的框架激增的原因Netty, RxJava, 反应流倡议反应堆项目。他们都在寻求推广这种类型的优化和编程模型。

还有一种有趣的新框架运动,它们利用了这一强大的功能,并试图相互竞争或互补。我说的是有趣的项目,比如Vert.x and Ratpack。我很确定还有更多其他语言的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

事件驱动编程如何帮助仅执行 IO 的 Web 服务器? 的相关文章

  • 在java中实现你自己的阻塞队列

    我知道这个问题之前已经被问过并回答过很多次了 但我只是无法根据互联网上找到的示例找出窍门 例如this http tutorials jenkov com java concurrency blocking queues html or t
  • 如何在进入新活动之前终止线程和处理程序

    大家好 在我尝试清理处理程序时 这段代码可能有点混乱 因为我一直在尝试追踪崩溃发生的位置 我有一个对话框活动 显示密码输入 进度条由线程和处理程序动画显示 似乎当我试图查看进度条是否完成并尝试终止线程时 当我尝试进入新活动时 我这样做的方式
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • 一段时间后终止线程的最 Pythonic 方法

    我想在线程中运行一个进程 它正在迭代一个大型数据库表 当线程运行时 我只想让程序等待 如果该线程花费的时间超过 30 秒 我想终止该线程并执行其他操作 通过终止线程 我的意思是我希望它停止活动并优雅地释放资源 我认为最好的方法是通过Thre
  • 如何在同一线程中创建JFrame以使其阻塞?

    出于调试目的 我需要在一个简单的窗口中在屏幕上绘制图像 Swing 在单独的消息循环线程中处理所有事件 这意味着如果我执行以下操作 while true Get screenshot BufferedImage screenshot MSW
  • Java基于参数的同步(名为互斥锁/锁)

    我正在寻找一种根据接收到的参数来同步方法的方法 如下所示 public synchronized void doSomething name some code 我想要方法doSomething同步基于name参数如下 线程 1 doSom
  • 运行外部进程的非阻塞线程

    我创建了一个 Java GUI 应用程序 它充当许多低级外部进程的包装器 该实用程序按原样运行 但迫切需要一项重大改进 我希望我的外部进程以非阻塞方式运行 这将允许我并行服务其他请求 简而言之 我希望能够在生成数据时处理来自外部进程的数据
  • Visual Studio 2010 的“线程”窗口中的 和 [Thread Destroyed] 详细信息

    我一直在尝试调试与一个应用程序的线程相关的一些问题 当我附加到应用程序时 我看到一个像这样的窗口 这个名为 Thread Destroyed 的线程是什么 应用程序代码肯定不会写这个名称 这意味着线程的调用堆栈不可用 采集引擎 线程在应用程
  • 如何使用 JAVA 代码以编程方式捕获线程转储?

    我想通过 java 代码生成线程转储 我尝试使用 ThreadMXBean 为此 但我没有以正确的格式获得线程转储 因为我们正在使用jstack命令 请任何人提供一些帮助 他们是否有其他方式获取线程转储 使用任何其他 API 我想要的线程转
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • 是否可以在Java中检查CPU是否是超线程的?

    我想知道可以运行的最佳线程数 通常 这等于Runtime getRuntime availableProcessors 但是 在支持超线程的 CPU 上 返回的数字是其两倍 现在 对于某些任务来说 超线程是好的 但对于其他任务来说 它没有任
  • 如何在 Android 中检查与配对设备的蓝牙连接状态

    我开发了一个蓝牙应用程序 它将连接到配对的设备并发送消息 但我必须先测试连接 我尝试了很多选择 但没有一个效果很好 那么您能给我发送任何可以做到这一点的代码示例吗 我创建了一个线程 但无法获得良好的连接状态来构建 if 函数 这是代码 pa
  • C:如果文件描述符被删除,阻塞读取应该返回

    我正在以阻塞的方式从设备 文件描述符中读取 可能会发生这样的情况 在不同的线程中 设备被关闭并且文件描述符被删除 不幸的是 读取没有返回或注意到并且一直阻塞 作为一种解决方法 我可以使用 select 作为超时来执行 while 循环 如果
  • 从另一个线程在主线程中运行代码

    在 android 服务中 我创建了线程来执行一些后台任务 我遇到一种情况 线程需要在主线程消息队列上发布某些任务 例如Runnable 有没有办法得到Handler主线程和帖子的Message Runnable从我的另一个线程到它 注意
  • Ruby 1.9.3 多核?

    昨天我读了一些关于 ruby 中线程的内容 比如本文 http www engineyard com blog 2011 ruby concurrency and you 而我一般的理解是 除了一些像 JRuby 这样的实现 有所谓的全局解
  • Device.BeginInvokeOnMainThread 的用途是什么?

    我希望有人向我解释什么是 Device BeginInvokeOnMainThread 以及它的用途是什么 还有一些使用案例的示例 只是添加一个例子 假设你有一个异步方法DoAnyWorkAsync如果你这样称呼它 仅作为示例 DoAnyW
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • 在 foreach 循环中启动一个新线程

    我有一个对象列表 我想循环该列表并启动一个新线程 传入当前对象 我写了一个我认为应该这样做的例子 但它不起作用 具体来说 线程似乎在每次迭代中都被覆盖 但这对我来说并没有什么意义 因为我每次都会创建一个新的 Thread 对象 这是我写的测
  • Shared Web Workers 是否会在单页重新加载、链接导航中持续存在

    共享网络工作者 http www whatwg org specs web apps current work shared workers introduction旨在允许来自同一站点 来源 的多个页面共享单个 Web Worker 但是
  • Webworker-threads:在工作线程中使用“require”可以吗?

    使用 Sails js 我正在测试 webworker threads https www npmjs com package webworker threads https www npmjs com package webworker

随机推荐