我正在运行一个基本节点服务器,它通过REST API调用对GE Historian数据库执行一些https get请求,并接收JSON数据。对于六台机器中的每台机器,我有四种不同的统计信息,它们每隔5-60秒定期使用递归超时调用自我更新。运行一段时间后,REST API调用将停止获取数据,而是产生ENOBUFS错误,此时必须重新启动Windows 7主机PC才能重新启动服务器。
我看过很多类似的帖子:
https://github.com/nodejs/node-v0.x-archive/issues/3269
Very simple Node.js client throws error ENOBUFS after many http requests
大多数线程都建议完全禁用https代理,但这并不能解决问题。我目前正在尝试通过为进行http调用的四个统计信息中的每一个创建https.Agent对象,为每个代理指定maxSockets = 1。现在似乎正确地回收港口;但是如果在大约一天左右的运行后其他尝试修复已经落到了它的脸上,我想发布并查看是否有人对可能修复此ENOBUFS错误的内容有其他想法。
提前感谢您的任何帮助。作为参考,这里是我为处理这些查询而创建的通用https请求函数和一个示例'queryOptions'对象:
代理声明:
var agent1 = new https.Agent;
agent1.maxSockets = 1;
queryOptions对象示例:
var queryOptions = {
agent : agent1,
hostname : "in02",
port : 8443,
path : '/historian-rest-api/v1/datapoints/currentvalue?tagNames=Compact_PME.INT_Accrued_Cycles_ThisRun[' + self.line.machineId + ']',
headers : {
"Accept" : "application/json",
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language" : "en-US,en;q=0.5",
"Accept-Encoding" : "gzip, deflate, br",
"Authorization" : "Bearer " + self.historianApi.token
}
};
getContent函数:
const getContent = function(queryOptions, callback) {
apiCallTimer = {
start : moment(),
end : null,
elapsed : 0
};
https.get(queryOptions, function(res) {
const statusCode = res.statusCode;
const contentType = res.headers['content-type'];
var error;
if (statusCode !== 200) {
error = new Error('Request Failed.\nStatus Code: ' + statusCode);
//console.log(res);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\nExpected application/json but received ' + contentType);
}
if (error) {
console.log(error.message);
// consume response data to free up memory
res.resume();
}
res.setEncoding('utf8');
var rawData = '';
res.on('data', function(chunk) {
rawData += chunk;
});
res.on('end', function() {
try {
//console.log('API call complete!');
var parsedData = JSON.parse(rawData);
apiCallTimer.end = moment();
apiCallTimer.elapsed = apiCallTimer.end - apiCallTimer.start;
var queryResultObject = {
queryOptions : queryOptions,
json : parsedData,
apiCallTimer : apiCallTimer
};
callback(queryResultObject);
} catch (e) {
e.queryOptions = queryOptions;
e.functionCalled = getContent;
callback(e);
//console.log(e.message);
}
});
}).on('error', function(e) {
callback(e);
});