如何在NodeJS应用程序中找到导致错误的MySQL查询



我在NodeJS和HapiJS之上构建了一个api。

该应用程序在启动时加载大量数据,然后将其保存在内存中。我有这个应用程序运行在一个有16 GB RAM的服务器上,所以在内存中保持4 GB RAM应该是可能的。

然而,每次应用程序启动时,此错误都会在日志中出现5次:

{ Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/Connection.js:425:13)
at Socket.g (events.js:291:16)
at emitNone (events.js:86:13)
at Socket.emit (events.js:185:7)
at Socket._onTimeout (net.js:339:8)
at ontimeout (timers.js:365:14)
at tryOnTimeout (timers.js:237:5)
at Timer.listOnTimeout (timers.js:207:5)
--------------------
at Protocol._enqueue (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/protocol/Protocol.js:141:48)
at Protocol.handshake (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/protocol/Protocol.js:52:41)
at Connection.connect (/home/ec2-user/daemons/liar_lies/node_modules/mysql/lib/Connection.js:136:18)
at /home/ec2-user/daemons/liar_lies/node_modules/knex/lib/dialects/mysql/index.js:106:18
at Promise._execute (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/debuggability.js:300:9)
at Promise._resolveFromExecutor (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:481:18)
at new Promise (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:77:14)
at Client_MySQL.acquireRawConnection (/home/ec2-user/daemons/liar_lies/node_modules/knex/lib/dialects/mysql/index.js:104:12)
at Object.create (/home/ec2-user/daemons/liar_lies/node_modules/knex/lib/client.js:231:16)
at Pool._createResource (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:326:17)
at Pool.dispense [as _dispense] (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:314:12)
at Pool.acquire (/home/ec2-user/daemons/liar_lies/node_modules/generic-pool/lib/generic-pool.js:392:8)
at /home/ec2-user/daemons/liar_lies/node_modules/knex/lib/client.js:281:19
at Promise._execute (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/debuggability.js:300:9)
at Promise._resolveFromExecutor (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:481:18)
at new Promise (/home/ec2-user/daemons/liar_lies/node_modules/bluebird/js/release/promise.js:77:14)
errorno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
fatal: true }

这是唯一的错误,每当应用程序启动时就会发生5次。

然而,该应用程序似乎确实获得了我期望它获得的大部分数据,所以无论什么查询抛出这个错误,它都一定相当模糊。

我该如何判断哪个查询会引发此错误?

stacktrace似乎没有提到我的代码中导致这种情况的那一行。(我觉得很沮丧。)

这些是我正在使用的模块:

"boom": "3.1.2",
"code": "2.1.0",
"fs": "0.0.2",
"glob": "6.0.4",
"glue": "3.1.0",
"good-console": "5.3.0",
"good-file": "5.1.2",
"hapi": "16.0.2",
"html-entities": "1.2.0",
"joi": "7.2.2",
"knex": "0.12.6",
"knex-logger": "0.1.0",
"multiline": "1.0.2",
"mysql": "2.12.0",
"path": "0.12.7",
"plugo": "0.3.1"

据我所知,只有两个函数在启动时调用数据库。这就是其中之一:

function build_maps_which_index_database_data(query, which_type_of_data_in_which_database_table) {
DB.knex.raw(query).then(
function(result) {
var count_of_database_results = result[0].length;
build_list_of_allowed_fields(result[0][0]);
for(var how_many_records_processed_so_far = 0; how_many_records_processed_so_far < count_of_database_results; how_many_records_processed_so_far++) {
var document = result[0][how_many_records_processed_so_far];
var profile_id = document['profile_id'];
document['which_type_of_data_in_which_database_table'] = which_type_of_data_in_which_database_table;
document['item_id'] =  uuidV4(); 
build_map_of_uuid_ids_to_documents(document);   
Object.keys(document).forEach(function(name_of_field_in_database) {
// avoiding name_of_field_in_database = profile_id
if (name_of_field_in_database != 'profile_id') {
var string_from_database = document[name_of_field_in_database];
build_map_of_santized_words_to_uuid_ids(name_of_field_in_database, string_from_database, document['item_id']);
}
});
}
})
.catch(function(e) {
console.log('Error:     calling code was get_map_of_santized_words_to_uuid_ids'); 
console.log('query was: ' + query); 
console.error(e);      
});
}

这些函数中的每一个都附带了一个"catch"子句,所以我认为如果这是错误的原因,那么我会在日志中看到。

问题中的错误不是由问题中包含的代码引起的。

要了解发送这些错误时发生了什么,请尝试使用环境变量DEBUG=knex:*运行应用程序。这将向您显示连接池中发生了什么,以及向DB发送了哪些查询。

export DEBUG=knex:*
cd ~/yourapp
node server.js

或者只是

cd ~/yourapp
DEBUG=knex:* node server.js

还要尝试从应用程序中删除代码,直到应用程序中的代码量最小,这仍然会产生这些错误。在那之后,应该很容易找到问题的根本原因。

您还可以做的一件事是将调试信息添加到

knex.on('query-error', function (err, obj) { ... }); 

事件,并检查是否捕捉到这些错误。

相关内容

  • 没有找到相关文章

最新更新