Что такое libuv в контексте Node.js?

«Что такое libuv в контексте Node.js?» — вопрос из категории Node.js Core, который задают на 35% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Libuv — это кроссплатформенная библиотека на C, которая является фундаментальным компонентом Node.js, реализующим цикл событий (event loop) и обеспечивающую асинхронный ввод-вывод. Она абстрагирует различия между операционными системами, предоставляя Node.js единый API для неблокирующих операций.

Ключевые функции libuv в Node.js:

  1. Реализация Event Loop:

    // Весь этот асинхронный код управляется libuv
    setTimeout(() => console.log('Timeout'), 0);
    setImmediate(() => console.log('Immediate'));
    fs.readFile('file.txt', () => console.log('File read'));
  2. Абстракция системных вызовов:

    • Файловые операции (fs модуль)
    • Сетевое взаимодействие (net, http модули)
    • Таймеры (setTimeout, setInterval)
    • Дочерние процессы (child_process)
  3. Thread Pool для блокирующих операций:

    // Эта операция выполняется в thread pool libuv
    const crypto = require('crypto');
    crypto.pbkdf2('password', 'salt', 100000, 64, 'sha512', (err, key) => {
    console.log(key.toString('hex'));
    });

Архитектура взаимодействия:

Node.js JavaScript Layer
        ↓
Node.js C++ Bindings (node.cc)
        ↓
Libuv (Event Loop + Thread Pool)
        ↓
Операционная система (epoll/kqueue/IOCP)

Практическое значение:

  • Кроссплатформенность: Один код работает на Windows (IOCP), Linux (epoll), macOS (kqueue)
  • Высокая производительность: Неблокирующий I/O позволяет обрабатывать тысячи соединений в одном потоке
  • Масштабируемость: Thread pool по умолчанию имеет 4 потока, настраивается через UV_THREADPOOL_SIZE

Пример мониторинга использования libuv:

const { performance, PerformanceObserver } = require('perf_hooks');
const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0]);
});
obs.observe({ entryTypes: ['measure'] });

performance.mark('start');
// Асинхронная операция через libuv
fs.readFile('largefile.txt', () => {
  performance.mark('end');
  performance.measure('File Read', 'start', 'end');
});