[英]NodeJS to NodeJS http requests hang
我有 2 项服务:1. worker 2.fetch 文档
两者都是 Nodejs 快递服务。
Worker 使用 Promise.all 向 fetch 服务发送 48 个 http POST(不要问为什么是 post 而不是 GET)请求,然后 fetch 服务获取所有 48 个文档(每个都在一个单独的请求中)并将它们发送回给 worker。
日志显示获取服务已成功完成所有操作,并且工作人员发送了所有 48 个请求,但显示部分响应(有时为 0,有时为 15/48,有时为 31/48,但从未完全成功)
工人似乎一直在等待响应,直到作业结束的 15 分钟超时并将其移至失败。
代码示例:
worker.js(服务 1 - 带有 express 的 NodeJS)
await Promise.all(docIDs.map(async (docID) => {
try {
logger.info(`Worker Get Document: Fetching ${docID.docID} transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
var document = await axios.post(getVariableValue("GET_DOCUMENT_SERVICE_URL"), docID, {
httpsAgent: new https.Agent({
rejectUnauthorized: false,
keepAlive: false
}),
auth: {
username: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_USERNAME"),
password: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_PASSWORD")
},
headers: {
"x-global-transaction-id": transactionId,
"timeStamp": timeStamp
}
});
logger.info(`Worker Get Document: Fetched ${docID.docID} Status: ${document.data.status}. transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
documents.push(document.data.content);
}
catch (err) {
const responseData = err.response ? err.response.data : err.message
logger.error(`Worker Get Document: Failed DocID ${docID.docID}, Error received from Get Document: ${responseData} - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
throw Error(responseData)
}
}));
fetch.js(服务 2 - 带有 express 的 NodeJS)
module.exports = router.post('/getDocument', async (req, res, next) => {
try {
var transactionId = req.headers["x-global-transaction-id"]
var timeStamp = req.headers["timestamp"]
logger.info(`GetDocumentService: API started. - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
var document = await getDocuemntService(req.body, transactionId, timeStamp);
var cloneDocument = clone(document)
logger.info(`GetDocumentService: Document size: ${JSON.stringify(cloneDocument).length / 1024 / 1024}. - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
logger.info(`GetDocumentService: API Finished. - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
res.status(200);
res.set("Connection", "close");
res.json({
statusDesc: "Success",
status: true,
content: cloneDocument
});
logger.info(`GetDocumentService: Response status: ${res.finished} . - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
}
catch (err) {
logger.error(`GetDocumentService: Error:${err.message} / Stack: ${err.stack}. - transaction ID: ${transactionId} / timeStamp: ${timeStamp}`, {})
res.status(500)
res.send("stack: " + err.stack + "err: " + err.message + " fromgetdocument")
}
});
因此,get 文档中的日志已满并显示成功。
工人的日志显示如下:
“取” X48
“获取” X0、X15、X31(获取 48 个文档的三种不同尝试)
我尝试将keep-alive更改为true。
还有什么我可能会丢失的吗? 任何人都知道为什么它永远挂起(至少 15 分钟,直到工作“超时”)
谢谢:)
对于测试,将您的请求限制为一次一个。 当一个完成发送下一个。
addWork 或 doWork 调用者需要等待
let queue = []
const sleep = (ms)=> new Promise((resolve)=>setTimeout(resolve,ms))
async addWork(work, cb, sleepMS) {
if (Array.isArray(work) queue = [...queue, ...work]
else queue.push(work)
if (cb) return doWork(cb, sleepMS)
}
async doWork(cb, sleepMS) {
let work = queue.pop()
var document = await getDocuemntService(work)
cb(document)
if (queue.length > 0) {
if (sleepMS) await sleep(sleepMS)
return doWork(cb, sleepMS)
}
}
一旦您确认一次一个工作,您就可以查看一个更复杂的工作队列。 我会检查 NPM 是否有一些东西我确信有一些东西可以处理这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.