javascript - 当大量请求非常快时如何解决“套接字挂断错误”
问题描述
我有一个 nodejs 应用程序,它聚合来自各种网站的内容。发出请求以使用请求流异步从不同来源获取提要。发出请求时,我经常收到套接字挂断错误。
err in accessing the link { Error: socket hang up
at createHangUpError (_http_client.js:331:15)
at TLSSocket.socketOnEnd (_http_client.js:423:23)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9) code: 'ECONNRESET' } https://arstechnica.com/?p=1488489
环境详情:节点版本 - v8.12.0
尝试了相关 SO 帖子中给出的一些建议,但我仍然遇到同样的错误。 NodeJS - “套接字挂断”实际上是什么意思?
import request from 'request';
import FeedParser from 'feedparser';
const extractor = require('unfluff');
export const getFeedsFromSource = function (urlfeed, etag, LastModified, callback) {
console.log(urlfeed, etag, LastModified);
const req = request({
method: 'GET',
url: urlfeed,
headers: {
'If-None-Match': etag,
'If-Modified-Since': LastModified,
Connection: 'keep-alive',
ciphers: 'DES-CBC3-SHA',
},
});
const feedparser = new FeedParser();
const metaData = {};
const htmlData = {};
const feedData = {};
// const pList = null;
req.on('response', function (response) {
const stream = this;
if (response.statusCode === 304) {
console.log('Source not modified: ', urlfeed);
}
if (response.statusCode === 200) {
metaData.etagin = response.headers.etag;
metaData.LastModifiedin = response.headers['last-modified'];
metaData.LastModifiedLocal = response.headers['last-modified'];
stream.pipe(feedparser).end();
}
});
req.on('error', (err) => {
console.log(`getFeed: err.message == ${err.message}`);
callback(err);
});
// req.end();
feedparser.on('readable', function () {
try {
const item = this.read();
if (item !== null) {
request({
method: 'GET',
url: item.link,
}, (err, info) => {
if (!err) {
htmlData.body = info.body;
const parsedData = extractor(htmlData.body, 'en');
feedData.author = [];
feedData.videos = [];
feedData.feedtitle = parsedData.title;
feedData.feedmainpicture = parsedData.image;
feedData.feedsummary = parsedData.description;
feedData.feedmaincontent = parsedData.text;
feedData.author.push(item.author);
if (item.author === null) {
feedData.author = parsedData.author;
}
feedData.feedurl = item.link;
feedData.copyright = item.meta.copyright;
// feedData.videos = parsedData.videos;
feedData.publishedDate = item.pubdate;
if (item.categories.length > 0) {
feedData.categories = item.categories;
feedData.feedtags = item.categories;
} else if (parsedData.keywords !== undefined) {
feedData.categories = parsedData.keywords.split(' ').join('').split(',');
feedData.feedtags = parsedData.keywords.split(' ').join('').split(',');
} else {
feedData.categories = [];
feedData.feedtags = [];
}
metaData.sourcename = item.meta.title;
callback(undefined, feedData, metaData);
} else {
console.log('err in accessing the link', err, item.link);
}
});
}
} catch (err) {
console.log(`getFeed: err.message == ${err.message}`);
}
});
feedparser.on('error', (err) => {
console.log(`getFeed: err.message == ${err.message}`);
});
feedparser.on('end', () => {
console.log('onend');
});
};
请帮我解决这个问题。
解决方案
生产应用程序中套接字挂断/重置的原因有很多。根据您的描述,我认为原因不是由于应用程序因请求而过载(除非您运行的是非常慢的机器)。IMO,最有可能的候选人是由于来自同一个 ip 的连接过多而受到远程服务器的限制(chrome 最多可以打开 8 个与任何单个服务器的连接,您应该尽量不要超过这个限制,尽管每个服务器都有不同的限制),以解决这个问题您应该执行以下操作之一:
- 添加主机请求池(基本设置
Agent.maxSockets
) - 使用代理服务(例如 Luminati)在多个源 IP 上分发请求(与高并发要求更相关)
还有一件事要记住,请求可能由于“自然”网络原因(例如糟糕的\不稳定的互联网连接、服务器繁忙的峰值)而失败,您应该始终在放弃之前至少重试一次请求。
推荐阅读
- ios - Swift:如何拆分字符串然后提取特定的子字符串?
- r - 有没有办法解决所有属性都具有 NA 值且行名具有 NA 值的行的问题?
- selenium - 我想用chrome上传
- java - 如何使用 Retrofit2
- objective-c - 有时 NSArrayController 在核心数据删除/更新后不刷新 NSTableView
- python - 如何有效地编程在向量上操作的特定酉变换,避免 np.dot
- javascript - 如何在类中创建 Element-create 方法
- angular - ng2-smart-table 列中的点击函数
- php - How to fetch data using loop PHP statement from mysql to ios?
- r - 在R中的数据框上应用函数