Как стать автором
Обновить

Node.js или Java: производительность, ресурсы, управление потоками, популярность и личный опыт

Время на прочтение 8 мин
Количество просмотров 38K
Недавно мы с коллегами обсуждали вопрос популярности некоторых технологий — в частности Java и node.js. После недолгого интернет-серфинга выяснилось, что именно эти технологии используют многие информационные гиганты для разработки и поддержания своих площадок в сети. Ниже, я приведу лишь малую часть.

Компании использующие Java:

image

Компании использующие node.js:

image

He менее интересным является и то, что по данным поиска на indeed.com (28.06.2019) по запросам Java Developer (30272 вакансии) и node.js developer (7401 вакансии), специалисты по этим технологиям довольно востребованы.

image

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

Почему их стоит сравнивать


Java — это язык, node.js — можно назвать экосистемой построенной на базе JS, и, прежде всего, на базе V8 — движка от Google.

Однако, когда мы говорим про Java, мы говорим не только про язык, а про виртуальную машину Java, а также всю экосистему и инфраструктуру построенную вокруг этой машины. Как минимум, их можно сравнивать по этому признаку — как результат, в обоих случаях, мы имеем среду исполнения. В случае Java — это виртуальная машина. В случае node.js — это движок V8 который представлен на большинстве ОС, таких как Windows, Linux, MacOS и менее известных.

Разработчики могут писать код пользуясь одним и тем же языком, и это будет работать более-менее одинаковым образом на разных ОС за счет того, что существует среда исполнения. Среда исполнения влияет на то, как происходит взаимодействие с ОС. Кроме того, их можно сравнивать т.к. они используются для решения похожего круга задач.

V8 и JVM


Когда в v8 попадает код JS, осуществляется just in time компиляция в байт код, который используется в виртуальной машине, код на JS выполняется все быстрее и быстрее.
Байт код — это промежуточный язык высокого уровня, поэтому в виртуальной машине Java пишут не только на Java, но также на Scala и Kotlin.

Есть предпосылки тому, что в ближайшем будущем для V8 можно будет использовать не только JS но и TypeScript или другие. На данный момент идет транспайлинг этих языков в JS. В будущем, они вероятно будут поддерживаться из коробки, и все будет работать намного быстрее.

Сейчас идет непрерывное развитие V8, и по большому счету, появление новых версий node.js связано с появлением новой версии движка V8. Они прямо взаимосвязаны.

Node.js: преимущества и недостатки


Node.js был создан Райаном Далом (Ryan Dahl) в 2009 году.

Сам node.js включает в себя несколько основных составляющих:

  • движок V8;
  • библиотеку libuv, которая отвечает за центральную часть node — цикл событий (event loop), который осуществляет взаимодействие с ОС, а так же за асинхронный ввод/вывод (I/O);
  • из набора различных JS библиотек и непосредственно самого языка JS.

Перейдем к его плюсам и минусам.

Плюсы:

  • легкость и скорость написания
  • легковесность
  • относительная простота (в сравнении с java)
  • npm (node package manager (огромное количество библиотек которые могут быть установлены в одну строку)
  • каждая библиотека попадает в дерево зависимостей и это все делается легко
  • постоянное развитие (сейчас активно развивается TypeScript (который привносит в JS типизацию, декораторы и используется например для Angular)

Минусы:

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

Преимущества и недостатки Java


В противовес сразу рассмотрим основные характеристики Java.

Плюсы:

  • скорость работы,
  • распространенность (в ВУЗАХ многих стран изучают java, также на java удобно изучать ООП),
  • огромный набор библиотек.

Минусы:

  • тяжеловесность,
  • некоторые парадигмы Java создавались давно и уже устарели,
  • JDK проприетарен, поэтому Java развивается медленно.

В последнее время JS начинает обгонять Java (и чем дальше, тем больше).
Также Java уходит из мира Android, ей на смену приходит Kotlin который хоть и использует JVM, но все же является другим языком.

Конфликт Oracle и Google


image

Java была создана компанией Sun, которая позже была выкуплена компанией Oracle и по сей день принадлежит ей. По этой причине, для многих компаний использование Java создает некоторые проблемы.

У Google возникли проблемы, когда Oracle начали с ними судебное разбирательство за использование Java в Android. Из-за этого Google очень активно принял Kotlin, который появился независимо. Java является проприетарной. Но есть виртуальная машина Oracle, а также открытая виртуальная машина Java (open JVM), которая используется в Linux и написана в open source. Иногда существуют некоторые несовместимости, но в последнее время их все меньше и меньше.

Кстати, Google так и не смог полностью отказаться от Java. В Dalvik, который используется как ядро в Android, вшит JVM. Возможно от этого уйдут, но сделать это будет очень сложно т.к. практически вся экосистема Android построена на Java — прежде всего — на использовании модернизированного JVM. И это, в какой-то момент, тоже было причиной конфликта между Oracle и Google, потому что Oracle запрещает просто так модернизировать JVM. Это самая важная часть Java. А сам язык можно использовать практически без ограничений.

Java vs node.js: производительность и ресурсоемкость


Прежде всего стоит отметить, что производительность Java намного выше чем у JS, и, соответственно, node.js.

image
Производительность node.js и Java

Если запустить какую-то простую задачу, вроде возведения в квадрат, то в тестах показатели могут различаться до 10 раз. Если запустить циклы в миллионы задач калькуляции, Java практически всегда будет превосходить node.js. Плюс, огромное различие между Java и node.js в том, что node является однопоточным, это является как его преимуществом, так и недостатком с другой стороны.

Java умеет работать с потоками, которые поддерживаются на уровне ОС, и получается, что программа написанная на Java наиболее полно использует возможности ОС. И если нужно написать высоконагруженное приложение, которое будет использовать большое количество вычислений, то Java для этого однозначно подойдет лучше. Проблема в том, что даже маленький сервер написанный на Java будет занимать много памяти — как на диске, так и оперативной.

Node.js является легковесным за счет архитектуры построенной на обработке событий. Он построен для работы в качестве веб-сервера и очень хорошо справляется с обслуживанием легковесных задач. Например, простой запрос вроде расчета чего-либо, или записи в базу данных происходит очень быстро. А если запросов становится очень много и мы хотим масштабировать систему в node, можно использовать веб-сервер Nginx или Apache. Можно завести много одинаковых инстансов node. Тогда все будет распределяться через балансировку нагрузки по round-robin. Если мы запустим 8 инстансов node на 16 ядер соответственно, ОС сама распределит инстансы между ядрами. Node этим не управляет, у него будет один поток.

Управление потоками в Java и node.js


В Java мы можем создать приложение и запустить в нем 8 потоков. За счет того, что происходит более тесное взаимодействие с ОС, можно распределить нагрузку.

Как известно, один из веб-серверов написанных на Java — это tomcat. Там можно четко проследить, что когда пользователь делает запрос, запускаются дополнительные потоки. А когда приходит запрос на node, цикл событий (event loop) будет обработан и отправлен обратно, затем придет следующий запрос. И за счет того, что мы не ждем результатов первого, он тоже будет подхвачен. Пока запросы легковесные, все хорошо. Однако, когда производится тяжелое вычисление, при наличии одного инстанса, node останавливается и наступает тайм-аут.

image
Управление потоками в Java

На node можно прописать буквально несколько строк кода и получить простейший веб-сервер. Естественно, для более широкого функционала, где будут нотификации, авторизации, логирование и т.д. это сложнее реализовать, но существуют фреймворки которые позволяют решать такие вопросы.

image
Управление потоками в node.js

На Java есть развитое API — concurrency api, которое позволяет работать с конкурентными потоками. Но в то же время, это является и одной из проблем т.к. конкурентность это очень сложная штука и далеко не каждый разработчик хорошо в этом разбирается.

Веб, REST API — это стихия node, и иногда именно его и используют. Но если мы имеем дело со сложными калькуляциями, все же лучше использовать Java.

Мой проект на Java


На Java у меня был интересный проект — распределенное приложение, основной задачей которого была обработка больших объемов графической информации для дальнейшего использования в каталогах. При создании каталога необходимо подготовить наборы большого количества изображений различных разрешений, которые будут использованы при создании каталога. Проще говоря — это приложение для автоматизации предпечатной подготовки каталога.

Раньше фотографам приходилось делать все вручную. Для начала нужно было использовать какое-то небольшое приложение для того, чтобы загрузить свои изображения. Далее, специалист создававший каталог должен был разработать структуру каталога через другое приложение. Потом, в другом приложении, создавался воркфлоу, который раскидывал картинки в ту структуру, которая была создана. В общем, процесс был довольно тяжелым. Использовался ImageMagick который есть на Linux, Windows, MacOS. Мы имели дело с Linux.

Например, в приложение была загружена .tiff картинка размером 200-300 мб, а из нее нужно было сделать картинки различных разрешений, что-то вырезать, или сделать подложку.
Первая версия приложения не справлялась с большой нагрузкой, не хватало даже сервера с 16 ядерным процессором. Мы улучшили архитектуру приложения для использования нескольких инстансов одновременно, чтобы кардинально не менять работу приложения. Запускалось много инстансов, которые взаимодействовали между собой и каждый из них обрабатывал кусок задачи. Было сложно, но нам удалось успешно реализовать все буквально за пару месяцев. И система до сих пор работает. В процессе пришлось разбираться с конкурентностью и различными аспектами взаимодействия.

Что-то из этого проекта все же можно было перенести на node, но некоторые вещи все равно пришлось бы делать на Java, т.к. там было много различных вычислений. В принципе, мы могли сделать части на node, которые бы вызывали определенные части на Java и использовать микросервисную архитектуру. Можно было использовать смешанный вариант. Но этот подход не всегда работает, т.к. разработчик специализирующийся на node, может не являться специалистом в Java и наоборот. А найти универсальных разработчиков гораздо сложнее.

Из опыта на node.js


Был проект по организации большого объема данных. Чем-то похоже на проект описанный выше. Только здесь у нас загружается файл, который содержит большой набор информации и подлежит валидации через сторонний сервис (написанный на java), несколько раз и по разным правилам. Нужно было обрабатывать сотни гигабайт информации, а node для этого не предназначен.

Проектировать архитектуру системы было особенно интересно, т.к. приложение состояло из нескольких микросервисов, в том числе сторонних. При работе со сторонним сервисом, который осуществлял валидацию, мы использовали RabbitMQ message broker. Мы отдавали стороннему серверу необходимую информацию и получали сообщение от RabbitMQ после окончания валидации, затем данные обрабатывались по частям, чтобы избежать out of memory.

И если изначально приложение обрабатывало файл, содержащий 10000 записей, то теперь может обрабатывать до миллиона. Нам все же удалось решить эту задачу с помощью node.js, хотя на Java ее можно было решить проще, однако заказчик хотел использовать именно node, т.к. нужна была единая инфраструктура и архитектура с микросервисами написанными на JS. Используя node решить задачу было намного сложнее, и потребовало больше времени, но node.js выигрывает за счет скалируемости. Именно поэтому сейчас мы можем наращивать количество воркеров и обрабатывать все больше и больше данных. На Java это происходило бы сложнее.

На самом деле, любую задачу можно решить и так и так, но тут стоит повториться: если есть много вычислений то лучше использовать Java, если вычислений не много, можно смело использовать node.

Итоги и перспективы: сможет ли node.js обогнать Java?


Сейчас идет к тому, что node.js часто будет использоваться как обертка, а начинку будут писать на других языках. Его недостатки давно известны. Например, такой условный недостаток как однопоточность уже исправлен. В последней версии node представлена возможность использования нескольких потоков.

Java изначально создавалась как легковесное решение заменяющее C++, а теперь стала тяжеловесной. Это как эволюция. Возможно, когда-нибудь появится что-то, что заменит и node.

image
Модули — Развитие Java vs node.js

Сейчас, по количеству заказов, и по моим ощущениям, node.js уже обогнал Java.
JS активно развивается и он будет меняться — возможно что-то придет ему на смену.
Сейчас не видно потенциального конкурента, который смог бы заменить Java и node.js.

Проблема в том, что развитие Java в последнее время идет довольно медленно, а node.js развивается с такой скоростью, что заменить его в ближайшее время не представляется возможным.
Теги:
Хабы:
-4
Комментарии 28
Комментарии Комментарии 28

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн