Объясни event loop в Node.js
Вопрос
Объясни, как устроен event loop в Node.js и почему однопоточный сервер выдерживает тысячи соединений.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
JS выполняется в одном потоке, ввод-вывод неблокирующий: колбэк регистрируется, ответ приходит позже
Цикл и асинхронность даёт libuv: сеть через epoll/kqueue/IOCP, файлы, DNS и crypto через пул потоков (4 по умолчанию)
Фазы: timers, pending, poll, check (setImmediate), close callbacks
Между колбэками опустошаются очереди process.nextTick и микрозадач промисов
Сервер масштабируется, пока колбэки короткие; CPU-работа блокирует всех
Тяжёлое выносить в worker_threads, асинхронные API, дробить работу
Что могут спросить следом
- Почему setImmediate внутри readFile срабатывает раньше setTimeout(0)?
- Как заметить, что event loop заблокирован в проде?
- Чем event loop Node отличается от браузерного?
Разбор
Node выполняет JavaScript в одном потоке, но почти никогда не ждёт. Когда код читает файл или делает сетевой запрос, он отдаёт операцию libuv и регистрирует колбэк. Сеть libuv обслуживает через системные механизмы вроде epoll, а файлы, DNS и тяжёлую криптографию через пул потоков, по умолчанию четыре.
Сам цикл проходит фазы: таймеры, отложенные колбэки, poll, где он ждёт и обрабатывает ввод-вывод, check с setImmediate и колбэки закрытия. После каждого колбэка Node опустошает очередь process.nextTick и очередь промисов.
Поэтому один поток держит тысячи соединений: на каждое тратится только короткое время обработки. Обратная сторона: если колбэк долго считает, например синхронно хеширует пароль или парсит огромный JSON, стоят все. Такое я выношу в worker_threads или использую асинхронные версии API. В проде блокировки видно по метрике задержки цикла, например через perf_hooks.monitorEventLoopDelay.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Event loop и libuv»
- Тяжёлый цикл без блокировки event loop
- Код-ревью: что блокирует event loop
- setTimeout(0) против setImmediate на верхнем уровне
- Что такое libuv
- Рекурсивный process.nextTick
- process.nextTick и setImmediate
- Event loop Node и браузера: в чём разница
- Порядок nextTick, промиса и setTimeout