简短的问题:假设一个非幂等的 post 操作,您如何防止 node.js 中的 post 请求处理程序在响应之前被多次调用,从而导致数据损坏?
具体案例:我有一个匹配的 API,它需要大约 2-3 秒才能返回(由于必须运行一个庞大的用户群)。有许多操作,用户可以在同一秒内简单地两次调用它(这是一个错误,但不在我的控制之下,因此回答这部分并不构成对根本问题的回答)。在这些条件下,为用户选择了多个匹配项,这是不可取的。理想的结果是所有这些快速请求都具有相同的最终结果。
具体约束:
node.js/express/sequelize。
如果我们添加一个队列,每个用户的请求都将位于所有其他用户的请求之上,这在流量大的时候可能会产生巨大的影响。
最佳答案
我提出了一个解决方案,其中服务器优雅地响应 same*
请求,因此不需要对客户端进行任何更改。
*
首先,我们需要确定什么构成了被视为“相同”的请求。当您计划这种优雅的同步响应时,您会在客户端请求中放置一个递增的计数器,这个计数器是将请求定义为 same
的唯一属性。但是由于您可能无法访问客户端并且没有这样的计数器,如果他们的 post
-body + url 相同,您可以将请求定义为相同(并且可能会抛出用户需要的内容也一样)。
因此,对于每个用户,当请求到达您的服务器时,您会立即保存请求。一种简单的方法是对 url + post
-body 进行哈希处理,例如使用 SHA-256
并将其保存在如下对象中:
请求[用户][hashOfRequest] = null
一旦您的服务器计算出它,该 null
将被替换为响应对象。现在您处理请求。
如果客户端再次发送same*
请求,您可以通过检查您的requests[user][hashOfRequest]
轻松找出。
如果服务器已完成处理,它将包含一个响应对象,您只需将该对象发送回客户端。如果它仍然是空的,您需要等待服务器(第一个请求)的处理完成。也许使用事件监听器或其他任务同步模式。
一旦服务器完成第一个请求,它将生成response
并将其保存在requests[user][hashOfRequest]=response
中并发出事件,以便潜在的等待客户也会得到响应。
没有更多的双重处理和来自客户端的连接丢失,响应没有到达它们,也由这种模式处理。
当然,您应该在适合您的(客户端)场景的时间后清理响应哈希表。可能在请求被放入哈希表后 10 分钟。
关于javascript - 在 Node.js 中保护非幂等后操作不被快速调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213724/