Используя Node, Express, MongoDB и Mongoose, я пытаюсь передать потенциально большое количество объектов (100K +) клиенту.Сервер узла останавливает прием соединений после потоковой передачи большого ответа
Это прекрасно работает для нескольких тысяч записей. Однако для записей 100K + запрос завершается успешно через минуту, , но все последующие запросы на сервер зависают, и мне нужно перезапустить сервер. Ошибок не видно.
Мысли о том, что может произойти? Мысли о лучшем способе отладки?
Вот мой код:
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write('{"meta":{"code":200},"objects":[');
Object
.find({ foo: 'bar' })
.sort({ createdAt: -1 })
.lean()
.cursor()
.on('error', function (err) {
console.error(err);
res.end();
})
.on('data', function (object) {
if (!first)
res.write(',');
else
first = false;
res.write(JSON.stringify(object));
})
.on('close', function() {
res.end(']}');
});
Edit:
После нескольких минут ожидания, я вижу следующее сообщение об ошибке, и последующие запросы начинают работать снова. Поэтому я подозреваю, что это связано с не закрытием соединений.
Error: write after end
at ServerResponse.write (_http_outgoing.js:443:15)
at QueryCursor.<anonymous> (<redacted>/server/models/object.js:431:11)
at emitOne (events.js:96:13)
at QueryCursor.emit (events.js:188:7)
at QueryCursor.Readable.read (_stream_readable.js:381:10)
at flow (_stream_readable.js:761:34)
at emitReadable_ (_stream_readable.js:433:3)
at wrapped (<redacted>/node_modules/newrelic/lib/transaction/tracer/index.js:183:28)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickDomainCallback [as _tickCallback] (internal/process/next_tick.js:122:9)
Edit 2:
Я никогда полностью не докопался до этого, но я подозреваю, что сервер удушья пытается JSON сериализации огромного количества записей. Я закончил с другим решением, сделав несколько запросов с постраничным доступом от клиента, а не сразу загружая записи. Смотри ниже.
Здесь потенциально много чего происходит. У вас есть какой-то способ узнать, где он может застрять? Небольшое количество записей, связанных с различными шагами, может помочь определить, где проблема. – tadman
Да, я посыпал некоторые каротажи. Отчасти проблема заключается в том, что запрос успешно завершается. Это просто последующие запросы, которые не работают, и я не знаю, почему. Это похоже на то, что сервер даже не принимает соединение. – nickpatrick
Если вы застряли в главном цикле событий по какой-то причине, это поведение, которое вы увидите, все приложение перестает принимать соединения или создает выходные данные. Возможно, у вас есть действительно сумасшедшая самореферентная структура данных, с которой не может справиться стриптизатор JSON, хотя он должен предупредить вас, если это так. – tadman