Посмотрим, насколько Fastify быстрее

Укрепить - название является девизом. По крайней мере, это то, что должна обозначать структура Node.js - Скорость.

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

Мне пришло в голову Fastify, поэтому я трижды написал один и тот же API - в чистом Node.js, в Express.js и в Fastify. А теперь позвольте мне показать вам, как Fastify работает на фоне конкурентов.

Начнем с написания API.

Давайте сначала установим Fastify

Как обычно, делаем это с помощью NPM: npm install fastify

Теперь мы можем написать сервер Fastify. Есть два способа разработки веб-приложения в этой структуре. Во-первых, есть возможность построить схему, которая будет использоваться для проверки ввода и вывода. На официальном сайте Fastify это хорошо видно:

Итак, здесь вы можете определить, что вы хотите получить, например. в качестве параметров запроса, и вы также можете использовать функцию preHandler, которая работает как промежуточное программное обеспечение - она ​​выполняется при каждом запросе.

Другой вариант немного менее сложен и больше напоминает Express.js. Я использовал его для теста, потому что на бумаге вариант схемы даже немного медленнее, в зависимости от его сложности.

Итак, пусть вас не пугает приведенный выше код, вот наш Fastify API:

Все три API отвечают на запросы на маршруте api. Они получают имя и фамилию в качестве параметров запроса и возвращают оба значения в ответе.

Запрос, который я возьму для теста: localhost:4000/api?name=john&lastname=doe.

API Express.js

Совсем не так сложно. А вот и API Express.js, который выглядит почти так же:

Комментарии: с помощью app.disable я отключил два содержимого в заголовке, перед ответом я установил для заголовка content-type значение text / plain - в Fastify это значение по умолчанию. С этими настройками мы получаем почти одинаковые заголовки во всех трех API.

Собственный / голый API Node.js

И последнее, но не менее важное: чистый сервер Node.js, полностью без какой-либо структуры.

Комментарии: в чистом Node.js нет res.send. Я добавил оператор if, чтобы сделать его справедливым - в конце концов, два других API проверяют маршрут при запросе. Без оператора if этот сервер узла отвечал бы на каждый запрос. Для content-type мне пришлось указать utf-8 вручную. В Express и Fastfiy это было автоматически в заголовке. Таким образом, все заголовки имеют одинаковый размер.

Тест

Для теста я использую MacBook Pro 13 дюймов 2018 года с 4-ядерным процессором Intel i5. Я убедился, что во всех тестах преобладали одинаковые условия. Каждый сервер тестировался индивидуально, все остальные источники запросов, кроме инструмента нагрузочного тестирования, были отключены.

Версия Node.js - 14.2.0. Я просто выполнил API с помощью команды node, PM2 или nodemon не использовались.

Тестер нагрузки

В прошлой статье я использовал apache bench. Но из-за HTTP-версий есть проблемы с Fastify, да и AB все равно очень старый. Поэтому я решил использовать wrk.
В macOS его можно установить с brew install wrk. В Linux его можно установить с sudo apt-get install wrk.

Это команда, которую я использовал для каждого API:
wrk -t12 -c400 -d10s http://localhost:4000/api?name=john&lastname=doe

12 - это количество используемых нами потоков, 400 - количество одновременных подключений. Все это длится 10 секунд.

Результаты, достижения

Конечно, я несколько раз засыпал каждый API тестером нагрузки - вот самые средние результаты.

Express.js

Thread Stats Avg Stdev Max +/- Stdev
 Latency 17.03ms 4.10ms 109.13ms 90.16%
 Req/Sec 1.86k 353.95 2.89k 88.92%
 222514 requests in 10.02s, 32.47MB read
 Socket errors: connect 0, read 248, write 0, timeout 0
Requests/sec: 22207.75
Transfer/sec: 3.24MB

Bare / Native

Thread Stats Avg Stdev Max +/- Stdev
 Latency 11.03ms 3.09ms 77.64ms 85.72%
 Req/Sec 2.77k 542.65 4.38k 86.17%
 331028 requests in 10.01s, 48.62MB read
 Socket errors: connect 0, read 257, write 0, timeout 0
Requests/sec: 33067.32
Transfer/sec: 4.86MB

Укрепить

Thread Stats Avg Stdev Max +/- Stdev
 Latency 9.75ms 3.17ms 79.39ms 87.88%
 Req/Sec 3.13k 729.47 11.94k 87.78%
 375177 requests in 10.10s, 54.74MB read
 Socket errors: connect 0, read 263, write 0, timeout 0
Requests/sec: 37147.37
Transfer/sec: 5.42MB

Результаты очевидны - Fastify быстрее, чем Express.js, и даже быстрее, чем Bare Node.js. Особенно меня удивило последнее. Но я также читал об этом в других тестах, не в последнюю очередь на официальном сайте Fastify. Кажется, это самый быстрый веб-фреймворк в мире Node.js.

Подводя итоги

С точки зрения производительности Fastify превосходит.

Честно говоря, тесты, которые показывают такую ​​разницу в производительности, часто являются очень нереалистичными ситуациями - в действительности вряд ли какой-либо веб-сервер будет засыпан таким большим количеством запросов одновременно.

Тем более, что решающую роль играет и аппаратная часть системы. Несмотря на превосходную производительность Fastify, я в первую очередь остановлюсь на Express.
Для меня и многих других того, что предлагает Express, вполне достаточно.

Вся экосистема лучше оснащена, и у Express есть больше ресурсов. Это делает его особенно удобным для новичков.

Наконец, различия в фреймворках невелики для многих целей - особенно для одного API или обслуживания статических ресурсов, переход на другой фреймворк легко возможен.

Понравилась эта статья? Если да, то получите больше похожего контента, подписавшись на наш канал на YouTube в Decoded!

Подробнее о Express.js:



Оставайся на связи со мной