首页 > 解决方案 > 运行端点时内存泄漏(将数据解析到数据库中)当我在本地执行时我得到:ENOBUFS

问题描述

我对连接到 mongoDB 的 Node(Express.js) 后端有疑问。

我试图将数据从其他服务器解析到我的数据库并且我得到像 ENOBUFS 这样的错误,或者当我使用在线服务器内存泄漏时,整个服务器都会下降。

这是代码:

 exports.sudRegList = [
    async function (req, res) {
        try {
            await Subjekti
                .estimatedDocumentCount().
                then(async count => {
                    try {
                        let response =await axios.get(`https://link.com?offset=${count}&limit=62000`,
                            {
                                headers: {"Key": "x"}
                            });
                        const subjects = response.data;
                        subjects.map(async subject => {
                            try {

                                let companyDetails = await axios.get(`link.com=${subject.mbs}&expand_relations=true`,
                                    {
                                        headers: {"Key": "x"}
                                    });
                                await Subjekti({
                                    mbs: subject.mbs,
                                    sud_id_nadlezan: subject.sud_id_nadlezan,
                                    sud_id_sluzba: subject.sud_id_sluzba,
                                    oib: subject.oib,
                                    ino_podruznica: subject.ino_podruznica,
                                    stecajna_masa: subject.stecajna_masa,
                                    datum_osnivanja: subject.datum_osnivanja,
                                    postupak: subject.postupak,
                                    likvidacijska_masa: subject.likvidacijska_masa,
                                    skracene_tvrtke: companyDetails.data.skracene_tvrtke && companyDetails.data.skracene_tvrtke.length > 0 ? companyDetails.data.skracene_tvrtke[0].ime : null,
                                    ulica: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].ulica : null,
                                    kucni_broj: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].kucni_broj : null,
                                    naziv_naselja: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_naselja : null,
                                    naziv_zupanije: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_zupanije : null,
                                }).save();
                            } catch (error) {
                                console.log("drugi axios", error);
                            }
                        });
                    } catch (error) {
                        console.log("prvi axios.", error);
                    }
                });
        } catch (err) {
            //Baci error 500...
            return apiResponse.ErrorResponse(res, err);
        }
    }
];

标签: javascriptnode.jsmongodbexpress

解决方案


如果您要调用的主题很多,那么.map()您可能会遇到同时进行中的请求过多的问题,这会导致内存使用量非常高。.map()不是承诺感知的,因此它不会关注从async回调返回的承诺,因此它只是一次运行整个.map()循环(而不是对项目进行排序)

为了减少内存使用,您不需要一次并行运行这么多请求。控制它的最简单方法是一个接一个地对您的请求进行排序(一次只有一个)。您可以通过将.map()循环更改为普通for循环来做到这一点,这样您的await语句实际上会暂停循环。这是一个如何做到这一点的例子:

exports.sudRegList = [
    async function (req, res) {
        try {
            let count = await Subjekti.estimatedDocumentCount();
            try {
                let response = await axios.get(`https://link.com?offset=${count}&limit=62000`, {
                    headers: {"Key": "x"}
                });
                const subjects = response.data;
                for (let subject of subjects) {
                    try {
                        let companyDetails = await axios.get(`link.com=${subject.mbs}&expand_relations=true`, {
                            headers: {"Key": "x"}
                        });
                        await Subjekti({
                            mbs: subject.mbs,
                            sud_id_nadlezan: subject.sud_id_nadlezan,
                            sud_id_sluzba: subject.sud_id_sluzba,
                            oib: subject.oib,
                            ino_podruznica: subject.ino_podruznica,
                            stecajna_masa: subject.stecajna_masa,
                            datum_osnivanja: subject.datum_osnivanja,
                            postupak: subject.postupak,
                            likvidacijska_masa: subject.likvidacijska_masa,
                            skracene_tvrtke: companyDetails.data.skracene_tvrtke && companyDetails.data.skracene_tvrtke.length > 0 ? companyDetails.data.skracene_tvrtke[0].ime : null,
                            ulica: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].ulica : null,
                            kucni_broj: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].kucni_broj : null,
                            naziv_naselja: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_naselja : null,
                            naziv_zupanije: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_zupanije : null,
                        }).save();
                    } catch (error) {
                        console.log("drugi axios", error);
                    }
                }
            } catch (error) {
                console.log("prvi axios.", error);
            }
        } catch (err) {
            //Baci error 500...
            return apiResponse.ErrorResponse(res, err);
        }
    }
];

请注意,如果您只想在任何异步操作失败时返回错误,您可以使用一个 try/catch 来处理所有错误,而不是像这样的三个单独的错误:

exports.sudRegList = [
    async function (req, res) {
        try {
            let count = await Subjekti.estimatedDocumentCount();
            let response = await axios.get(`https://link.com?offset=${count}&limit=62000`, {
                headers: {"Key": "x"}
            });
            const subjects = response.data;
            for (let subject of subjects) {
                let companyDetails = await axios.get(`link.com=${subject.mbs}&expand_relations=true`, {
                    headers: {"Key": "x"}
                });
                await Subjekti({
                    mbs: subject.mbs,
                    sud_id_nadlezan: subject.sud_id_nadlezan,
                    sud_id_sluzba: subject.sud_id_sluzba,
                    oib: subject.oib,
                    ino_podruznica: subject.ino_podruznica,
                    stecajna_masa: subject.stecajna_masa,
                    datum_osnivanja: subject.datum_osnivanja,
                    postupak: subject.postupak,
                    likvidacijska_masa: subject.likvidacijska_masa,
                    skracene_tvrtke: companyDetails.data.skracene_tvrtke && companyDetails.data.skracene_tvrtke.length > 0 ? companyDetails.data.skracene_tvrtke[0].ime : null,
                    ulica: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].ulica : null,
                    kucni_broj: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].kucni_broj : null,
                    naziv_naselja: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_naselja : null,
                    naziv_zupanije: companyDetails.data.sjedista && companyDetails.data.sjedista.length > 0 ? companyDetails.data.sjedista[0].naziv_zupanije : null,
                }).save();
            }
        } catch (err) {
            //Baci error 500...
            return apiResponse.ErrorResponse(res, err);
        }
    }
];

推荐阅读