【发布时间】:2022-01-12 01:02:05
【问题描述】:
背景:
我的 Express.js Web 服务器目前正在提供一个包装 SOAP 服务的 API(一些我无法更改的遗留服务)。 SOAP 服务需要处理动态数量的项目,处理每个请求大约需要 1.5 秒。 Nginx 服务器的超时时间为 60 秒。
问题:
对于此 API 的请求,例如假设需要超过 60 秒才能完成,我观察到该服务正在自动重新触发(我假设由 Express.js)。因此,如果在原始请求中我希望向表中插入 50 条记录,现在由于 API 的重新触发,我最终插入了 100 条记录(重复)。
这是显示问题的日志框架/示例:(敏感信息已被剥离)
January 10, 2022 15:35:44 [... ee905] - Starting myAwesomeAPI() <-- Original API trigger
January 10, 2022 15:36:44 [... ff870] - Starting myAwesomeAPI() <-- Re-trigger happens
January 10, 2022 15:36:54 [... ee905] - Completed myAwesomeAPI() <-- Original API ends (inserts 50 records in the table)
January 10, 2022 15:37:54 [... ff870] - Completed myAwesomeAPI() <-- Re-triggered API ends (inserting another 50 records in the table resulting in duplication)
我尝试过的:
重现问题并检查重新触发是否可以独立于 nginx。将 Nginx 超时设置为 60 秒,我将 Express 服务器的超时更改为 10 秒,并使用以下命令处理 15 个项目(在处理完成之前强制超时):
const express = require("express")
const server = express()
server.setTimeout(10000) <-- sets all requests to have a 10 seconds timeout
// myAwesomeAPI code
测试表明,10 秒后,超时“确实”重新触发了 API,并且 15 项重复(我看到插入了 30 条记录)。所以这告诉我 API 正在被 Express.js 重新触发。
问题:
- 如何阻止重新触发的发生,是否有快速服务器配置来启用/禁用超时自动重新触发?
解决方案和想法:
-
自从
max items = 100(由团队设置)以来,将 Nginx 和 Express.js 超时增加到 300 秒应该是一个快速但肮脏的修复。我知道将异步 API 调用与某个近似时间联系起来纯属愚蠢(告诉我尝试向我团队中的其他工程师解释这一点;-p),所以我想避免这种方法。 -
创建具有某些列组合的复合键并对表实施插入限制。将此与检查复合键是否已插入/存在于表中并决定跳过/插入相结合。这种方法似乎更好一些。
-
另一种方法是在收到 API 调用后立即响应(这将关闭请求),然后继续处理请求。像这样的东西(灵感):https://www.bennadel.com/blog/3275-you-can-continue-to-process-an-express-js-request-after-the-client-response-has-been-sent.htm.
这将使我独立于平台的超时设置,但会带走响应与不同项目状态的实时性,并增加通过其他查找等跟踪请求状态的复杂性。
【问题讨论】:
标签: javascript node.js rest express nginx