簡體   English   中英

NodeJS 到 NodeJS http 請求掛起

[英]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 分鍾,直到工作“超時”)

謝謝:)

我在這里只有猜測,但我覺得它們是強烈的猜測。

  1. Axios 的默認超時為無,但我猜某處有 900 秒的超時。 編輯:此超時很可能在服務器端 web 服務器中。
  2. 您正在用 48 個請求在幾分之一秒內敲擊服務器。 我並不感到驚訝這是失敗的。
  3. 他們的服務器可能會限制您的速度或只是過載。

對於測試,將您的請求限制為一次一個。 當一個完成發送下一個。

簡單的工作隊列示例 - 未測試

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM