javascript - 在 JS (Node.js) 中同时管理多个长时间运行的任务

标签 javascript node.js multithreading node-worker-threads

Golang 开发者在这里,尝试学习 JS (Node.js)。
我习惯于在 Go 中使用 goroutine,为了简单起见,我们假设它们只是线程(实际上它们并不完全是线程,更像 Green Threads,但请耐心等待!)。
现在想象一下,我想创建某种可以运行 endlessTask 的服务。例如,它可能是一个从 websocket 接收数据并保持内部状态更新的函数,稍后可以查询。现在,我希望能够同时为多个用户提供服务,并且每个用户还可以在某个时候停止他们正在进行的特定任务。在 Go 中,我可以为我的 endlessTask 生成一个 goroutine。 ,在请求调度程序中存储某种 session ,以跟踪每个任务属于哪个用户。
我怎样才能在 JS 中实现这样的东西?我浏览了 Node.js API 文档,发现了一些有趣的东西:

  • 集群:似乎不是我正在寻找的
  • 子进程:可以工作,但我会为每个客户端/用户生成 1 个进程,我认为开销会很大
  • 工作线程:更像是它,但文档指出它们“对于执行 CPU 密集型 JavaScript 操作很有用”和“Node.js 内置的异步 I/O 操作比 Worker 更有效”

  • 我不确定在没有多线程或多处理的情况下如何处理这种情况。在这种情况下,工作线程解决方案是否可行?
    任何意见或建议将不胜感激。谢谢!

    最佳答案

    Imagine now that I want to create some kind of service that can run some endlessTask which, for example, could be a function that receives data from a websocket and keeps an internal state updated


    因此,您需要考虑事件和事件处理程序,而不是线程,因为这是 nodejs 架构的核心,尤其是对于 I/O。因此,如果您希望能够读取传入的 webSocket 数据并在它到达时更新一些内部状态,那么您所做的就是为传入的 webSocket 数据设置一个事件处理程序。然后,只要有数据等待读取并且解释器返回事件循环,就会调用该事件处理程序。
    您不必为此或任何类型的循环或类似的东西创建任何线程结构。只需添加正确的事件处理程序并让它在有可用传入数据时调用您。

    Now, I want to be able to serve multiple users at the same time and each of them can also stop their specific ongoing task at some point.


    只需为每个 webSocket 添加一个事件监听器,您的 nodejs 服务器就可以轻松地为多个用户提供服务。当用户断开他们的 webSocket 时,监听器会自动消失。除非您想更新内部状态,否则在这方面没有其他事情可做或清理,在这种情况下您也可以监听 disconnect事件。

    In Go, I could just spawn a goroutine for my endlessTask, store some kind of session in the request dispatcher to keep track to which user each task belongs.


    我不知道 goroutines 但有很多用于存储用户状态的选项。如果它只是当您已经拥有 webSocket 并且不需要它持续存在时您需要能够获取的信息,那么您可以直接将状态添加到 webSocket 对象。该对象将在您收到 webSocket 事件时可用,因此您可以随时在有传入数据时更新它。您还可以将状态放在其他地方(数据库,由套接字或用户名索引的 Map 对象,您需要能够查找它的任何内容) - 这实际上取决于状态到底是什么。

    I'm not sure how I could handle this scenario without multi-threading or multi-processing. Would the worker threads solution be viable in this case?


    你所描述的听起来不像任何需要集群、子进程或工作线程的东西,除非你对数据做的事情是 CPU 密集型的。只需对每个 webSocket 上的传入数据使用事件监听器,就可以让 nodejs 非常高效和异步的 I/O 处理发挥作用。这是它最擅长的事情之一。
    请记住,nodejs 中的 I/O 可能与您习惯的有所不同。您不会创建阻塞读取循环以等待 webSocket 上的传入数据。相反,您只需为传入数据设置一个事件监听器,它会在传入数据可用时调用您。

    涉及集群、子进程或工作线程的时间是,当您在 Javascript 中处理传入数据的 CPU 处理量超过单个内核可以处理的量时。如果/当您证明您的 nodejs 服务器中的 CPU 使用率存在可伸缩性问题时,我只会去那里。然后,您会希望采用一种仅添加几个其他进程或线程来分担负载(不是每个连接一个)的架构。如果您有特定的 CPU 繁重的进程(自定义加密或压缩是经典示例),那么您可能会帮助创建一些其他进程或工作线程来处理 CPU 繁重工作的工作队列。或者,如果它只是增加可用于处理传入数据的整体 CPU 周期,那么您可能会去集群并让每个传入的 webSocket 被分配到一个集群并仍然使用前面描述的相同事件处理逻辑,但是现在您有了 webSockets拆分为多个进程,因此您有更多的 CPU 可以扔给它们。

    关于javascript - 在 JS (Node.js) 中同时管理多个长时间运行的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66395130/

    相关文章:

    javascript - ReactJS:从 JSON 文件中提取数据时出错

    javascript - 无法将对象从 Angular 服务传递到 Controller

    node.js - sails-auth 生成器不起作用

    node.js - 如何在 typescript 中导入 recursive-readdir

    multithreading - SPARK可以正确使用多核吗?

    javascript - 重试 promise 直到解决(递归错误太多)

    javascript - 函数不可能返回构造函数并创建新实例吗?

    node.js - 使用Node js将数据打印到热敏打印机

    ruby - 处理并发 ruby​​ 线程池中的异常

    Python - 使用队列时多处理线程不会关闭