1

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

应用程序.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,就像它崩溃并重新启动一样。任何人都可以提供的任何提示将不胜感激。我会提供任何我能提供帮助的信息。

4

1 回答 1

0

我终于能够想出解决这个问题的办法。在慢慢回滚潜在原因之后,它归结为使用 Node 中间件 Multer ( https://github.com/expressjs/multer ),它本质上是 BusBoy 的中间件包装器。我将它换成了一个名为 Multiparty ( https://github.com/andrewrk/node-multiparty ) 的不同模块,就像那样,iisnode 停止崩溃。

我没有从 iisnode 获得任何日志,但没有给我任何信息,所以根本原因仍然未知,不幸的是其他工作优先。这是生成的代码,以防其他人碰巧遇到类似的事情(原始基于 multer 的代码可以在原始帖子中看到):

特快路线:

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);
    }
};
于 2015-08-12T06:00:50.550 回答