我有一个小应用程序,它使用Express在Node.js中获取请求路由,例如:
http://192.168.0.10:3000/db/
这里,/ db /是路由。这很好,我有一个运行的db.js文件,它调用一个期望的MySQL服务器需要很长时间(可能是几分钟)才能返回大型连接的结果。如果我偶尔发出一些请求,一切都没问题,因为我修改了我的设置以获得可接受的超时。我在Node.js控制台上得到如下结果:
GET /db/ 200 88569.341 ms - 89
所有肉汁。但是,现在我正在使用Apache Bench(我知道它并不受大家欢迎)来锤击Node.js服务器,看看当我尝试向MySQL服务器(在一台单独的机器上)发出大量请求时会发生什么。如果我使用这种技术通过Node.js将并发请求增加到MySQL服务器(在一台单独的机器上),我会间歇性地开始获取以下内容:
GET /db/ - - ms - -
我不知道这意味着什么或如何使用它,但我相信它意味着发生了一些不好的事情,因为测试运行所需的时间减少了2/3左右(约700秒到约400秒)我在代码中添加的控制台日志记录是 not 输出足够的时间来指示每个请求都在被服务。有关如何调试此问题的任何提示,以找出某些请求似乎失败的原因?
注意:我正在使用的MySQL包是mysql
,但我认为这不是问题所在。
如果有帮助,这是我的路线的代码。提醒一下,此代码以低并发性工作。如果我通过Apache / PHP而不是Node.js发出请求,它也可以正常工作。
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
/* GET users listing. */
router.get('/', function(req, res, next) {
// The code below borrowed in part from the NPM MySQL package documentation at:
// https://www.npmjs.com/package/mysql
var connection = mysql.createConnection({
host:/* my host */,
user:/* username */,
password:/* password */,
database:/* my db name */
});
connection.connect();
connection.query({sql:/* some huge join query */;',timeout:999999}, function(err, rows, fields) {
if (err) {
var output = "error! " + err;
console.log(output);
res.send(output);
}
else {
var output = "good: " + JSON.stringify(rows);
console.log(output);
res.send(output);
}
});
connection.end();
});
module.exports = router;
答案 0 :(得分:1)
调试重负载的#1提示是确保处理和记录所有可能的错误路径。 connection.end()
和var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var requestCntrStart = 0;
var requestCntrDone = 0;
var requestCntrErr = 0;
/* GET users listing. */
router.get('/', function(req, res, next) {
// The code below borrowed in part from the NPM MySQL package documentation at:
// https://www.npmjs.com/package/mysql
++requestCntrStart;
var connection = mysql.createConnection({
host:/* my host */,
user:/* username */,
password:/* password */,
database:/* my db name */
});
// log any other errors
connection.on('error', function(err) {
++requestCntrErr;
console.log("Uncaught connection error: ", err.code); // 'ER_BAD_DB_ERROR'
logMatch();
});
function logMatch() {
if (requestCntrStart !== (requestCntrDone + requestCntrErr)) {
console.log("Unmatched requestCntrs: requestCntrStart = " + requestCntrStart +
", requestCntrDone = " + requestCntrDone + ", requestCntrErr = " + requestCntrErr);
} else {
console.log("Matched requestCntrs");
}
}
connection.connect(function(err) {
if (err) {
++requestCntrErr;
console.log("connection.connect() error: ", err);
logMatch();
}
});
connection.query({sql: 'some huge join query',timeout:999999}, function(err, rows, fields) {
if (err) {
++requestCntrErr;
var output = "connection.query() error! " + err;
console.log(output);
res.send(output);
logMatch();
}
else {
++requestCntrDone;
res.send(output);
logMatch();
}
});
connection.end(function(err) {
if (err) {
++requestCntrErr;
console.log("connection.end() error: ", err);
logMatch();
}
});
});
module.exports = router;
都会收到可能报告错误的回调。而且,仅仅因为您将一个连接限制设置为100,000并不意味着您已经删除了系统可能允许的同时连接数量的所有限制。通常会有许多不同的级别,从您使用的库到它在底层操作系统上的位置可能会发生一直限制。
我建议您创建更强大的日志记录,以便查看每个开始实际完成的请求,并确保所有可能的错误路径都有日志记录。运行时,您应该看到"匹配的requestCntrs"作为最后一个日志条目之一。如果没有,则某些操作未正确完成,并且未记录错误。
foreach