Кластеризация¶
Процесс кластеризации представляет собой одну из форм горизонтального масштабирования и позволяет приложениям полноценно использовать все имеющиеся мощности процессора несмотря на однопоточность Node.js.
Кластеризация - это запуск нескольких экземпляров одного приложения для распределения между ними обработки поступающих запросов.
Для получения максимальной производительности количество запущенных экземпляров не должно превышать количество ядер процессора. Дополнительные (дочерние) экземпляры создаются основным процессом, являются независимыми самостоятельными серверами и привязываются к тому же порту, где запущен основной процесс. Совокупность основного и дочерних экземпляров называется кластером.
Создание Node.js кластера¶
Рассмотрим создание Node.js кластера на примере.
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Для кластеризации используется встроенный в Node.js модуль cluster
. При запуске сервера проверяется, является ли текущий процесс основным. Если да, то на основании данных о процессоре, полученных с помощью модуля os
, запускаются дополнительные экземпляры, которые при запуске попадают в ветку else
.
Каждому дополнительному экземпляру назначается уникальный идентификационный номер.
В итоге при запуске сервера Node.js в консоли должно быть приблизительно следующее (в зависимости от процессора).
1 2 3 4 |
|
Также в примере обработана ситуация, когда один из дополнительных экземпляров завершается, например, в случае ошибки, и ему на замену создается новый экземпляр.
1 2 3 4 5 6 7 8 9 |
|
Чтобы удостовериться в том, что запросы обрабатываются одним из экземпляров кластера, используется функция промежуточной обработки.
1 2 3 4 5 6 7 8 |
|
При выполнении GET-запроса по адресу http://127.0.0.1:7000
в консоли вы должны увидеть следующее.
1 |
|
Cluster API¶
Для работы с кластером Node.js модуль cluster
реализовывает ряд методов, свойств и событий.
Методы и свойства модуля cluster
:
fork()
- создает новый экземпляр приложения;disconnect()
- отключает от кластера все созданные дополнительно экземпляры, параметром принимает callback-функцию, которая будет вызвана, когда все экземпляры будут отключены;isMaster
- булевое значение, еслиtrue
- значит текущий процесс является основным;isWorker
- булевое значение, еслиtrue
- значит текущий процесс является дочерним.
События модуля cluster
:
fork
- инициируется при создании нового экземпляра приложения, в качестве аргумента callback-функции передается созданный экземпляр;
1 |
|
listening
- возникает в момент запуска экземпляра сервера при вызове функции listen()
, параметры callback-функции - экземпляр и объект с данными адреса, на котором он запущен;
1 2 3 4 5 |
|
online
- возникает после того, как новый экземпляр посылает основному процессу сообщение в том, что он появился в кластере;
1 |
|
message
- инициируется при отправке одним из дочерних экземпляров сообщения основному процессу (сообщение посылается вызовом у дочернего процесса метода send()
);
1 |
|
disconnect
- инициируется при разрыве IPC канала, предназначенного для обмена данными между процессами;
1 |
|
exit
- возникает, когда завершается один из дочерних процессов.
1 |
|
Перечисленные выше методы, свойства и события относятся ко всему кластеру. Теперь рассмотрим методы и свойства дочернего экземпляра:
disconnect()
- разрывает IPC канал между основным и текущим дочерним процессами, но сам дочерний процесс не завершается, пока у него будут активные подключения, новых подключений он уже не принимает;kill()
- завершает дочерний экземпляр, начиная с разрыва канала IPC и заканчивая присвоением статуса завершения процесса, который передается методуkill()
аргументом (по умолчанию0
);send()
- посылает экземпляру данные и инициирует у него событиеmessage
;
1 2 3 4 |
|
isConnected()
- возвращаетtrue
, если дочерний процесс связан с главным процессом IPC каналом;isDead()
- возвращаетtrue
, если экземпляр уже завершенid
- уникальный идентификатор процесса;process
- экземпляр созданного дочернего процесса;exitedAfterDisconnect
- булевое значение, еслиtrue
, то экземпляр был завершен вызовомkill()
илиdisconnect()
.
Список событий дочернего процесса идентичен списку событий кластера и события экземпляра относятся только к нему самому.