В ожидании HTTPS-запроса событие l oop застревает и не отвечает на проверку работоспособности - NodeJS + kubernetes - PullRequest
1 голос
/ 21 января 2020

Я действительно потерян из-за этого, я пробовал много вещей, таких как изменение тайм-аутов, использование разных библиотек и т. Д. c, я надеюсь, что кто-то может понять, почему это происходит с реальным кодом, который доставляет мне проблемы. Я постараюсь быть кратким.

Краткое текстовое объяснение:

Работник выбирает задание из очереди, использует модуль и передает ему всю необходимую информацию. Затем модуль отправляет Promise.all для всех запросов в другой микросервис с помощью ax ios. Затем этот микросервис отправляет еще один запрос https в службу, которую я не контролирую, и на ответ очень часто уходит много времени (1-10 минут). Служба должна возвратить документ, который микросервис затем вернет модулю, используемому работником.

При ожидании медленного обслуживания, чтобы ответить на микросервис, событие l oop не может ответить на исправность. проверки, сделанные kubernetes.

Код:

Рабочий модуль:

const axios = require('axios');
const { getVariableValue } = require("redacted");
const logger = require('redacted');
const https = require('https')

module.exports = webApiOptiDocService = {

    async getDocuments(docIDs, transactionId, timeStamp) {

        try {

            var documents = [];

            await Promise.all(docIDs.map(async (docID) => {

                var document = await axios.post(getVariableValue("GET_DOCUMENT_SERVICE_URL"), docID, {
                    httpsAgent: new https.Agent({
                        rejectUnauthorized: false,
                        keepAlive: true
                    }),
                    auth: {
                        username: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_USERNAME"),
                        password: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_PASSWORD")
                    },
                    headers: {
                        "x-global-transaction-id": transactionId,
                        "timeStamp": timeStamp
                    }

                });

                documents.push(document.data.content);

            }));

            return documents

        }
        catch (err) {

            const responseData = err.response ? err.response.data : err.message

            throw Error(responseData)

        }

    }

}

Микросервис, который затем получает эти запросы:

API:

const express = require('express');
const router = express.Router();
const logger = require('redacted');
const getDocuemntService = require('./getDocumentService')
var clone = require('clone')

module.exports = router.post('/getDocument', async (req, res, next) => {

    try {

        var transactionId = req.headers["x-global-transaction-id"]

        var timeStamp = req.headers["timestamp"]

        var document = await getDocuemntService(req.body, transactionId, timeStamp);

        var cloneDocument = clone(document)

        res.status(200);

        res.json({
            statusDesc: "Success",
            status: true,
            content: cloneDocument
        });

    }
    catch (err) {

         res.status(500).send("stack: " + err.stack + "err: " + err.message + " fromgetdocument")

    }

});


Это модуль getDocument. js, который затем использует:

const axios = require('axios');
const { getVariableValue } = require("redacted");
const logger = require('redacted');
const https = require('https')
const fileType = require('file-type')
var request = require('request-promise-native')

module.exports = async (docID, transactionId, timeStamp) => {

    try {



        var startTime = Date.now();



        const documentBeforeParse = await request.get(getVariableValue("WEBAPI_OPTIDOCS_SERVICE_URL_GET") + docID.docID, {

            strictSSL: false,
            headers: {
                'x-global-transaction-id': transactionId
            },
            timeout: Infinity
        }).auth(getVariableValue("WEBAPI_OPTIDOCS_SERVICE_USERNAME"), getVariableValue("WEBAPI_OPTIDOCS_SERVICE_PASSWORD"))
        const parsedDocument = JSON.parse(documentBeforeParse)

        var document = {
            data: {
                mimeType: parsedDocument.mimeType,
                fileName: "",
                content: parsedDocument.content
            }
        }

        // const document = await axios.get(getVariableValue("WEBAPI_OPTIDOCS_SERVICE_URL_GET") + docID.docID, {
        //     maxContentLength: 524288000, //500 MB in Bytes
        //     maxBodyLength: 524288000, //500 MB in Bytes
        //     method: 'get',
        //     httpsAgent: new https.Agent({
        //         rejectUnauthorized: false
        //     }),
        //     auth: {
        //         username: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_USERNAME"),
        //         password: getVariableValue("WEBAPI_OPTIDOCS_SERVICE_PASSWORD")
        //     },
        //     headers: {
        //         'x-global-transaction-id': transactionId
        //     }
        // });

        if (document.data.mimeType == "") {

            if (recoverMimeType(document.data.content)) {

                document.data.mimeType = recoverMimeType(document.data.content).ext

            }
            else {

                throw Error("Missing mime type can not be recovered.")

            }

        }

        var fixedMimeType = fixMimeType(document.data.mimeType);

        document.data.fileName = docID.docPartsPrefixName + fixedMimeType

        var returnDocument = {
            fileName: document.data.fileName,
            content: document.data.content,
            mimeType: document.data.mimeType
        }

        return returnDocument;

    }
    catch (error) {

        throw Error(error);

    }

}

function fixMimeType(mimeType) {
    return "." + mimeType
}

function recoverMimeType(content) {

    return fileType.fromBuffer(Buffer.from(content[0], "base64"))

}

Я удалил все регистраторы, но сохранил в закомментированном запросе топора ios, который попытался заменить. для запроса на проверку, имеет ли это какое-либо отношение к этому.

По сути, микросервис получает 50-150 запросов через Promise.all, и после довольно большой выборки, в конечном итоге d ie будет действительно медленные ответы, потому что они не отвечают на проверки здоровья.

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Для любого, кто сталкивался с этим и искал ответ, то, что я наконец-то сделал, это исправило, это резко увеличило память, которую мое приложение получало от kubernetes. похоже, это была не проблема l oop, а проблема производительности. Гудлак!

0 голосов
/ 21 января 2020

В модуле вашего работника вы используете await с обещанием все,

обещание все работает асинхронно, а ожидание - для синхронного кода, который блокирует событие l oop.

, которое вы можете использовать await. ключевое слово для вызова функций, которое возвращает обещания работать с ними синхронно

PFA для асинхронного / ожидающего использования

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

...