О Node.js, Go и параллелизме

Node.js

В недавнем интервью Райан Дал, создатель Node.js, сказал следующее о модели параллелизма Node:

Я думаю, что Node — не лучшая система для построения массивного веб-сервера. Я бы для этого использовал Go. И честно говоря, причиной, по которой я оставил Node, было понимание, что это не самая лучшая система для серверной стороны из когда-либо созданных.

Это было сильно. Почему Дал, так тяжело работавший над созданием и продвижением Node.js, просто забросил свое творение и продвигает какое-то другое? Что это означает для Node.js и его огромного сообщества?

Давайте вкратце припомним историю.

История Node.js

Node.js был вдохновлен событийно-ориентированной архитектурой асинхронного ввода-вывода NGINX.

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

Чтобы это осуществить, Дал построил Node.js смешав вместе другие возможности, такие как веб-сервер API, V8 и JavaScript, который является однопотоковым.

Он очень верил в эту модель параллелизма. В его первой речи, представлявшей Node.js, он заявил, что мы неправильно производим ввод-вывод. Использование многопоточности ошибочно для разработчиков и приводит к более высокому потреблению CPU и памяти из-за переключения контекста и стека вызовов, который берет каждый поток.

И исходя из несомненного успеха Node.js, мы можем подытожить, что он был прав. Так что же заставило его так сильно изменить свое мнение?

Модель параллелизма Go

Go это язык, созданный для параллелизма. Он основан на CSP (communicating sequential processes — сообщении последовательных процессов), шаблоне, описанном в 1977 году Тони Хоаром (Tony Hoare).

В кратком изложении, Go является многопоточным и блокирует ввод-вывод. Почему он не медленный? Трюк в том, что все управляется рабочим циклом Go: когда вы создаете goroutine, вы на самом деле не создаете поток (как и сопрограмму). Что Go делает, так это сочетает независимые сопрограммы в набор потоков, так что когда сопрограмма создает «затор», рабочий цикл автоматически перемещает остальные сопрограммы в другой, работоспособный поток.

Другой важной частью является то что эти goroutine сообщаются через каналы, так что вместо разделения памяти по потокам (что приводит к ужасным проблемам с замыканием), они передают ссылки на данные. Это гарантирует что только один goroutine имеет доступ к данным в каждую отдельную единицу времени.

Не сообщаться путем разделения памяти; вместо этого разделять память путем сообщения.

И это несомненно работает. Рост Go ошеломляет и сегодня он является отличным выбором для решений параллелизма. Конечно, его и критикуют (обычно сравнивая с моделью акторов Erlang), но его успех очевиден. Есть много историй успеха людей, перешедших с других языков на Go.

Заключение

Что же случится с Node.js в свете того, что существует, возможно, лучшая модель параллелизма?

Ничего. Go, возможно, лучше чем Node в плане параллелизма, но это не так важно, если вы не строите массивный веб-сервер. И даже если строите, вы всегда можете прибегнуть к масштабированию (для которого в стандартной библиотеке Node есть встроенный модуль). Что же касается параллелизма, одна из самых обсуждаемых проблем модели Node (функция обратного вызова) уже решена. Начиная с версии 7.6 Node поддерживает async/await из коробки, что не требует обратных вызовов и не блокирует ввод-вывод.

Но что в этой истории интересно и из-за чего Node выживет и будет развиваться, это то, что Node стал популярен не только благодаря своей революционной модели параллелизма. Фактически, в то время для других языков были другие библиотеки, позволявшие не блокировать ввод-вывод, например Twisted для Python и Netty для Java.

Node стал одной из самых больших платформ для создания веб-приложений благодаря своему сообществу и экосистеме. Для этого были причины:

  • Во-первых, язык: JavaScript уже широко использовался в веб-разработке фронтенда. Возможность использовать его же и для бэкенда означало возможность стать full-stack-разработчиком, пользуясь всего одним языком, что снижало барьер для веб-разработки.
  • Во-вторых, модель параллелизма. Но не только из-за ее производительности. Ключевым моментом было то что все стали строить библиотеки, основанные на этой новой модели, в отличие от библиотек, упомянутых выше, которые не блокировали ввод-вывод в мире многопоточности.
  • Поскольку экосистема является важным фактором, свою роль сыграло и наличие хорошо сконструированного менеджера пакетов – NPM.

А эти вещи никуда не денутся в ближайшее время.

***
Подписывайтесь на наш канал в Telegram!
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх