Какой бэкэнд лучше для скорости? Мы провели 1 миллион тестов, чтобы узнать

Какой бэкэнд лучше для скорости? Мы провели 1 миллион тестов, чтобы узнать

28 июля 2025 г.

Тест веб-приложения, которые предлагают услуги по сокращению URL-адресов, представляют собой класс чувствительных к задержке систем, часто используемых в качестве ориентиров для оценки эффективности бэкэнд. В то время как микро-кармаркинг с тривиальными приложениями, такими какHello Worldраспространено, в таких подходах отсутствует сложность реальных вариантов использования, включающих логику маршрутизации, анализ запросов, проверка данных и взаимодействие с постоянным хранилищем. Чтобы учесть это ограничение, эта статья оценивает производительность минимальной, но реалистичной службы сокращения URL, реализованной в двух широко используемых бэкэнд -структурах: node.js с экспресс -и Java с Spring Boot. Популярное представление состоит в том, что Java быстрее Node.js. Или, node.js, интерпретируется медленнее, чем скомпилированное приложение Java. Эта статья пытается запустить реальное приложение для проверки понятия.

Node.js работает на однопоточной модели цикла событий, ограничивая выполнение по умолчанию одним ядром ЦП, если только явно настроен для кластеризации. Напротив, Spring Boot использует виртуальную машину Java (JVM), которая изначально поддерживает многопоточное чтение и способна использовать все доступные ядра процессора. Эта фундаментальная архитектурная разница привела к общему восприятию, что приложения на основе Java превосходят на основе JavaScript в нескольких ядрах.

Основная цель этого исследования-оценить, является ли это восприятие верным для реального приложения. Эксперимент проходит в два этапа. На первом этапе приложение Express с одним инстансом сравнивается со стандартным приложением Spring Boot. На втором этапе приложение Express складывается в четырех процессах для использования нескольких ядер, и его производительность снова сравнивается с приложением Spring Boot. Все реализации выполняют идентичные операции, в том числе генерирование коротких URL -адресов, их разрешение и выполнение базовой проверки и ввода -вывода. Тесты проводятся в контролируемых условиях с последовательными рабочими нагрузками и измеряются с использованием пропускной способности и задержки в качестве основных метрик.

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

Настройка теста

Все тесты были проведены на MacBook Pro с чипом Apple M2 с 12 ядрами процессора и 16 ГБ оперативной памяти.

Для обеспечения высококачественной генерации нагрузки широко признанныйБомбардираИнструмент был использован. Инструмент был настроен для отправки случайного и уникального URL в корпусе запроса, отформатированного как строка JSON.

Bombardier был настроен на моделирование постоянной нагрузки из 100 параллельных соединений, выполнив в общей сложности 1 млн запросов на тест.

Были использованы следующие версии программного обеспечения, все они были в курсе тестирования:

  • Node.js: v24.4.1,Выражать:V5
  • Java:v21.0.8,Весенний ботинок:v3.5.3

Все тесты взаимодействовали сPostgresqlБаза данных, широко принятая система с открытым исходным источником с объектно-релационной базой с более чем 35-летним развитием. PostgreSQL хорошо известен своей надежностью, обширным набором функций и сильной производительностью.

Единственная таблица с именемshortenedurlsиспользовался для всех операций базы данных. Эта таблица хранит как оригинальные, так и укороченные URL -адреса. Его структура заключается в следующем:

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

Приложения

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

Приложение оценивает производительность в следующих операциях:

  • JSON SAINGING с входящего запроса
  • Проверка запроса
  • Чтение базы данных через ORM
  • JSON Response Construction

Реализация для каждого приложения подробно описана ниже:

Node.js

https://gist.github.com/mayankchoubey1/e299cd8dbd2147a9cb7fe401381d91ea?embedable=true

Весенний ботинок

https://gist.github.com/mayankchoubey1/256D27253BE534181432E75CF0476CCCCCEMBEDABLE=TRUE

Чтения

Каждый тест проводится с 1 миллионами запросов. Следующие показатели производительности записываются для каждого тестового прогона:

  • Общее время для выполнения 1 миллиона запросов
  • Запросы в секунду (RPS)
  • Средняя задержка
  • Средняя задержка
  • Максимальная задержка
  • Использование процессора
  • Использование памяти

Важно отметить, что потребление ресурсов - специфично ЦП и использование памяти - так же важно, как и необработанная производительность. Более быстрое время выполнения, которое несет значительно более высокие затраты на ресурсы, может не обеспечить практическую ценность в реальных сценариях.

Фаза 1 -го тестирования - одиночное прикладное тестирование

На первом этапе эталон выполняется для одного экземпляра Express App. Spring Boot уже использует все ядра, поэтому обе фазы одинаковы для Spring Boot.

Результаты в форме диаграммы следующие:

В конфигурации с одним средством приложение Spring Boot продемонстрировало более высокую пропускную способность, чем его Express Countershape. В частности, Spring Boot достиг приблизительно 10 тысяч RP, в то время как Express поддерживал около 7,3 тыс. RPS. Хотя абсолютная разница умеренная, она не подходит для критических средств. Также наблюдается, что приложение Spring Boot входит в более высокое потребление ресурсов, демонстрируя повышенное использование ЦП и следы памяти по сравнению с экспресс -реализацией.

Важно отметить, что приложение Express по умолчанию работает на одном ядре ЦП из-за однопоточной архитектуры событий Node.js. Следовательно, сравнение не хватает паритета при распределении ресурсов процессора. Это ограничение рассматривается на последующей фазе посредством многопроцессной кластеризации приложения Express.

Фаза 2 -го тестирования - кластерное тестирование приложения

На втором этапе эталон выполняется для кластерного экземпляра Express App. Как упоминалось ранее, Spring Boot уже использует все ядра, поэтому обе фазы одинаковы для Spring Boot.

Однако существует тонкая разница в конфигурации. Размер пула базы баз данных для приложения Spring Boot составляет 10. В то время как в кластерном режиме Express Application использует в 4 раза больше размера пула (40 подключений). Это снова сделает тест несправедливым. Чтобы быть справедливым, размер бассейна весенних ботинок увеличивается до 40.

Модифицированное приложение.properties:

spring.datasource.hikari.maximum-pool-size=40
spring.datasource.hikari.minimum-idle=40

Размер бассейна для приложения Express сохраняется в 10. В режиме кластера он увеличится до 40, поскольку четыре работники будут установлены модулем кластера. Приложение Express остается прежним, за исключением основного модуля:

import cluster from "node:cluster";
import express from "express";
import { handleRequest } from "./expressController.mjs";

const numClusterWorkers = 4;

if (cluster.isPrimary) {
  for (let i = 0; i < numClusterWorkers; i++) {
    cluster.fork();
  }

  cluster.on(
    "exit",
    (worker, code, signal) => console.log(`worker ${worker.process.pid} died`),
  );
} else {
  const app = express();
  app.use(express.json());

  app.post("/shorten", handleRequest);

  app.listen(3000);
}

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

Результаты следующие:

Теперь результаты интересны. Кластерное приложение Express превосходит Spring Boot в коэффициент 2. Другими словами, приложение Express предлагает два раза RPS (25K) по сравнению с Spring Boot (12K).

Тем не менее, увеличение производительности не стало бесплатным. Использование процессора Express Cluster составляет ~ 400%, в то время как использование памяти составляет ~ 700 м.

In cluster mode, Express offers much better performance but uses a significant amount of resources.

Краткое содержание

Табличное резюме прогонов заключается в следующем:

Один процесс запуска

Кластерный запуск

Спасибо за чтение!


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE