gpt4 book ai didi

spring - NestJS 提供者需要无状态吗?

转载 作者:行者123 更新时间:2023-12-03 08:23:34 25 4
gpt4 key购买 nike

我是一名长期学习 NestJS 的 Spring 开发人员。这些相似之处是如此惊人,我很喜欢这让我变得高效。然而,一些文档让我对一件事感到困惑。

我尝试将 Nest“提供者”比作具有默认范围的 Spring beans。例如,我创建 @Injectable 服务类,并将它们视为类似于 Spring @Services。因此,我假设这些服务类需要是线程安全的 - 无状态等。但是,the Nest documentation here对我来说有点含糊,有点暗示这可能没有必要(强调我的):

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully safe for our applications.

如果单个请求不在自己的线程中处理,那么 Nest 提供程序可以包含可变状态吗?应用程序需要确保每个传入请求都以“干净的状态”开始 - 例如例如,使用 NestInterceptor 初始化该状态。但对我来说,该文档显示提供程序是作为单例创建的,因此可以用作类似于数据包装容器的东西,就像 Java 中的 ThreadLocal 一样。

我读错了,还是这是 Nest 和 Spring 之间的行为差​​异?

最佳答案

您确实应该使请求处理无状态。

我对 Spring 一无所知,但在 NestJS(以及一般的异步 JavaScript)中,它是单线程的,但不会阻塞 I/O。这意味着同一服务实例的同一线程可以同时处理多个请求。它一次只能做一件事,但它可以在前一件事等待数据库查询时开始做下一件事,或者等待请求完成传输,或者等待外部服务响应,或者等待文件系统传递文件内容等。

因此,在一个线程中,使用一个服务实例,可能会发生这种情况:

  • 请求 A 进来。
  • 针对请求 A 调度数据库查询。
  • 请求 B 进来。
  • 针对请求 B 调度数据库查询。
  • 请求 A 的数据库查询返回,并发送响应。
  • 请求 B 的数据库查询返回,并发送响应。

这对于状态意味着它将在请求之间共享。如果您的服务在异步操作的一个步骤中设置实例属性,则另一个异步操作可能会在第一个异步操作完成之前启动,并为该实例属性设置一个新值,这可能不是您想要的。

我相信 Nest 文档提到的“全局状态”不是每个请求,而是一般配置状态。例如外部服务的 URL 或数据库的凭据。


还值得一提的是, Controller 接收一个请求对象,它代表该特定请求。向该请求对象添加属性是很常见的,例如 the current authenticated user例如。可以传递请求对象,以对该架构友好的方式提供 Controller 和服务上下文。

关于spring - NestJS 提供者需要无状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67131275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com