Azure 网站 - NodeJS - 崩溃

Azure Website - NodeJS - Crash

我们在 S1 托管计划下有一个 Azure 网站 运行 一个节点应用程序并连接到 DocumentDB。每次我们尝试将媒体上传到 DocumentDB 时,node.exe 进程都会崩溃并重新启动。附件的大小似乎无关紧要。当 运行 在本地 Mac 上时,我不是 iisnode 容器中的 运行,只是直接节点,所以我无法在我的受控环境中重现它。这实质上会导致应用程序看起来冻结或始终重定向到登录页面。这是代码(我使用的是 1.0.3 vs docdb nodejs sdk):

app.js

app.post('/portal/add/media',isAuthenticated, 
  [ multer({ dest: './uploads/'}), portalCrud.addMedia.bind(portalCrud)]);

portalCrud.js

addMedia: function (req, res) {
    var self = this;
    var file = req.files.attachment;
    var errorCallback = function(error) {
        console.log("Document updated with media ERROR..." + error);
        res.status(error.status || 500);
        res.render('error', {
            message: error.message,
            error: error
        });
    };

    var readableStream = fs.createReadStream(file.path);
    readableStream.on("close", function() {
        fs.unlinkSync(file.path);
    });

    var options = {
        slug: file.originalname,
        contentType: file.mimetype
    };

    // the attachment has been added, now get the parent object to update
    self.dao.getDocument(req.body.docId, false, function (gdErr, parentDocument) {
        handleError(gdErr, errorCallback);
        if(gdErr) return;

        self.dao.addAttachment(parentDocument._self, readableStream, options, function (err, attachment) {
            handleError(err, errorCallback);
            if(err) return;
            res.status(200).send(req.header('Referer'));
        });
    });
}

dao.js

addAttachment: function (docLink, readableStream, options, callback) {
    var self = this;
    self.client.createAttachmentAndUploadMedia(docLink, readableStream, options, function (err, resp) {
        if (err) {
            callback(err);
        } else {
            callback(null, resp);
        }
    });
}

我对 Azure 还是很陌生。我已尽可能多地打开日志记录,但没有发现任何表明问题的信息。似乎没有发出任何事件,我似乎无法启用或找到 iisnode 日志。 d:\home\LogFiles\Application\logging-errors.txt 似乎没有任何记录,但我可以看到,每当我进行上传时,节点进程都会获得一个新的 PID,就像它崩溃并重新启动一样。任何人都可以提供的任何提示将不胜感激。我会尽我所能提供帮助。

我终于想出了解决这个问题的方法。在慢慢回滚潜在原因后,它归结为使用 Node 中间件 Multer (https://github.com/expressjs/multer) which is essentially a middleware wrapper for BusBoy. I switched that out for a different module called Multiparty (https://github.com/andrewrk/node-multiparty),就这样,iisnode 停止了崩溃。

虽然我没有从 iisnode 获得任何日志给我任何信息,所以根本原因仍然未知,不幸的是其他工作正在优先考虑。这是生成的代码,以防其他人碰巧 运行 变成类似的东西(原始的基于 multer 的代码可以在原始的 post 中看到):

快递路线:

app.post('/portal/add/media',isAuthenticated, portalCrud.addMedia.bind(portalCrud));

addMedia函数:

addMedia: function (req, res) {
    var self = this;
    var callback = function(fields, file, readableStream) {
        var errorCallback = function(error) {
            res.status(error.status || 500);
            res.render('error', {
                message: error.message,
                error: error
            });
        };
        var options = {
            slug: Math.floor(Date.now() / 1000) + "_" + file.originalFilename,  // prepend date in seconds for uniqueness
            contentType: file.headers["content-type"]
        };

        self.dao.getDocument(fields.docId, false, function (gdErr, parentDocument) {
            handleError(gdErr, errorCallback);
            if(gdErr) return;

            self.dao.addAttachment(parentDocument._self, readableStream, options, function (err, attachment) {
                handleError(err, errorCallback);
                if(err) return;

                parentDocument[fields.fieldName] = attachment;

                // update the parent document
                self.dao.updateDocument(parentDocument, function(updErr, updResp) {
                    handleError(updErr, errorCallback);
                    if(updErr) return;

                    fs.unlink(file.path);
                    res.redirect(req.header('Referer') || '/');
                });
            });
        });
    };

    self.fileUploadHelper.uploadFile(req, res, callback);
}

最后是 FileUploadHelper:

FileUploadHelper.prototype = {
    uploadFile: function(req, res, cb, noStream) {
        var fields = {};
        var form = new multiparty.Form();
        form.on('field', function(name, value) {
            fields[name] = value;
        });
        form.on('file', function(name, file) {
            console.log("Upload File >>>");
            console.log("path: " + file.path);
            console.log("filename: " + file.originalFilename);
            console.log("size: " + (file.size / 1024));
            console.log("headers: " + JSON.stringify(file.headers));

            if(noStream) {
                cb(fields, file);
            } else {
                var readableStream = fs.createReadStream(file.path);
                cb(fields, file, readableStream);
            }
        });

        form.parse(req);
    }
};