我们有一个Node.js脚本,每分钟运行一次以检查我们的应用程序的状态。通常,它工作得很好。如果服务启动,它将以0退出。如果服务停止,它将以1退出。一切都很好。节点HTTP请求永久挂起
但每隔一段时间,它只是有点停止。控制台报告“呼叫状态API ...”并在那里无限期地停止。它甚至不会在Node内置的两分钟超时时间内超时。没有错误,没有。它只是坐在那里,等待着,永远。这是一个问题,因为它会阻止正在运行的以下状态检查作业。
在这一点上,我的整个团队已经看过它,我们谁也无法弄清楚什么情况会使它挂起。我们已经建立了一个从开始到结束的超时时间,以便我们可以继续进行下一个工作,但实际上这会跳过状态检查并创建盲点。所以,我向你们提出了一个好问题。
这里的脚本(除去名称/网址):
#!/usr/bin/env node
// SETTINGS: -------------------------------------------------------------------------------------------------
/** URL to contact for status information. */
const STATUS_API = process.env.STATUS_API;
/** Number of attempts to make before reporting as a failure. */
const ATTEMPT_LIMIT = 3;
/** Amount of time to wait before starting another attempt, in milliseconds. */
const ATTEMPT_DELAY = 5000;
// RUNTIME: --------------------------------------------------------------------------------------------------
const URL = require('url');
const https = require('https');
// Make the first attempt.
make_attempt(1, STATUS_API);
// FUNCTIONS: ------------------------------------------------------------------------------------------------
function make_attempt(attempt_number, url) {
console.log('\n\nCONNECTION ATTEMPT:', attempt_number);
check_status(url, function (success) {
console.log('\nAttempt', success ? 'PASSED' : 'FAILED');
// If this attempt succeeded, report success.
if (success) {
console.log('\nSTATUS CHECK PASSED after', attempt_number, 'attempt(s).');
process.exit(0);
}
// Otherwise, if we have additional attempts, try again.
else if (attempt_number < ATTEMPT_LIMIT) {
setTimeout(make_attempt.bind(null, attempt_number + 1, url), ATTEMPT_DELAY);
}
// Otherwise, we're out of attempts. Report failure.
else {
console.log("\nSTATUS CHECK FAILED");
process.exit(1);
}
})
}
function check_status(url, callback) {
var handle_error = function (error) {
console.log("\tFailed.\n");
console.log('\t' + error.toString().replace(/\n\r?/g, '\n\t'));
callback(false);
};
console.log("\tCalling status API...");
try {
var options = URL.parse(url);
options.timeout = 20000;
https.get(options, function (response) {
var body = '';
response.setEncoding('utf8');
response.on('data', function (data) {body += data;});
response.on('end', function() {
console.log("\tConnected.\n");
try {
var parsed = JSON.parse(body);
if ((!parsed.started || !parsed.uptime)) {
console.log('\tReceived unexpected JSON response:');
console.log('\t\t' + JSON.stringify(parsed, null, 1).replace(/\n\r?/g, '\n\t\t'));
callback(false);
}
else {
console.log('\tReceived status details from API:');
console.log('\t\tServer started:', parsed.started);
console.log('\t\tServer uptime:', parsed.uptime);
callback(true);
}
}
catch (error) {
console.log('\tReceived unexpected non-JSON response:');
console.log('\t\t' + body.trim().replace(/\n\r?/g, '\n\t\t'));
callback(false);
}
});
}).on('error', handle_error);
}
catch (error) {
handle_error(error);
}
}
如果你们能看到的任何地方,这可能可能挂无输出或超时,那会是非常有帮助!
谢谢 詹姆斯·坦纳
编辑:附:我们直接使用https
而不是request
,这样脚本运行时我们不需要进行任何安装。这是因为脚本可以在没有自定义安装的情况下在分配给Jenkins的任何构建机器上运行。
我会检查您的响应回调中的状态码,如果它不等于200,则会引发错误。 – Keith
哦,对不起@凯斯,我不认为我清楚这一点。成功取决于回应。 200代码不一定足够。 –
编辑我的评论。在完成打字之前,我会点击“添加”。 –