Nodejs запрашивает ETIMEDOUT при отправке большого количества запросов - PullRequest
1 голос
/ 26 марта 2019

Я отправляю каждые 50 мс запрос (т. Е. 20 запросов / сек), чтобы получить тело сайта, но после 20-30 секунд выполнения я получаю ошибку ETIMEDOUT в каждом запросе.Я установил process.env.UV_THREADPOOL_SIZE = 128;

Я попытался установить для THREADPOOL_SIZE значения, превышающие 128.

    for(let i in urls) {
        setTimeout(function() {
            getBody(i); //It is function with a request
        },50*i);
    }
    request({
        url:url,
        method:'GET',
        timeout:3000,
        headers: {
            'Accept': '*/*',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
        }},
        (err,res) => {

пакет: запрос

Пожалуйста, помогите мне, я хочуотправить большое количество запросов в секунду.

1 Ответ

0 голосов
/ 26 марта 2019

UV_THREADPOOL_SIZE равно ограничено до 128, поэтому вы не можете увеличить его, передав это число.

Его размер по умолчанию равен 4, но его можно изменить при запускевремя, задав для переменной среды UV_THREADPOOL_SIZE любое значение (абсолютный максимум равен 128).

Во-вторых, в модуле request нет свойства timeouts, правильное имя свойства: timeout.

Если вы выполняете несколько запросов параллельно одному и тому же серверу, установка его на 3000 может быть слишком низкой, особенно если сервер не может обработать такое количество запросов.

Это можетбыть одной из причин, по которой вы получаете столько ошибок тайм-аутов.Поэтому, во-первых, увеличьте это число, чтобы увидеть, есть ли у вас тайм-ауты.

Во-вторых, есть два типа таймаутов:

Существует два основных типа тайм-аутов: тайм-ауты соединенияи читать таймауты.Тайм-аут соединения происходит, если истекло время ожидания, когда ваш клиент пытается установить соединение с удаленным компьютером (соответствует вызову connect () в сокете).Тайм-аут чтения происходит каждый раз, когда сервер слишком медленный для отправки части ответа.

Вы можете проверить, был ли тайм-аут истечения времени ожидания соединения, выполнив следующие действия:

if(err.connect === true) // connection timeout.

Кроме того, если вы используете один и тот же домен, чтобы увеличить скорость и сократить время ожидания, вы можете разрешить IP-адрес и напрямую подключиться к серверу, используя IP-адрес.

Я не тестировал скрипт, но он показывает вам, как вы это сделаете, может потребоваться незначительное исправление

const dns = require('dns');
const { promisify } = require('util');
const URL = require('url');
const dnsResolve = promisify(dns.resolve);


const ipCache = {};

async getIP(host) {

    // Use LRU cache with expiration...

    if(ipCache[host]) // If it's set, it's either the resolved IP or dnsResolve Promise
        return ipCache[host];

    ipCache[host] = dnsResolve(host);

    const [ip] = await ipCache[host]; // Wait until the promise is resolved

    ipCache[host] = ip;

    return ip;
}

async getBody(url) {

    const { host } = new URL(url);


    const ip = await getIP(host);

    // Build the URL using the IP address instead of the domain
    request( /* ... */)
}   

Вы также должны ограничить запросы, потому чтоВы можете наводнить свою собственную сеть.Если вы попробуете это на VPS, вы, вероятно, получите меньше тайм-аутов, чем запуск сценария на локальном компьютере.

Например, в AWS есть несколько оптимизированных для сети экземпляров, которые лучше подходят для больших затрат.запросов, использование одного из этих экземпляров позволит вам делать больше успешных запросов, чем на локальном компьютере.

Так что это либо ограничение вашей собственной сети, либо ограничение сервера, на котором вы отправляете запросычтобы в обоих случаях вам нужно было дросселировать запросы, чтобы избежать ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...