Скількі запыткаў на самае справа можа обрабацаваць сервер Node.js?
Скількіх запітоў насправды можа апрацуе сервер Node.js? Тэсты навантажэння Express на Heroku і AWS у параўнанні з Django, оцінка працездатнасці у 40 тыс. запітоў на секунду, а такса, што спам’чвае API.
Крыніцы: How Many Requests Can a Real-World Node.js Server-Side App Handle?
Кожны, хто толькі пачынае працаваць з Node.js, рано чым ставіць тое ж практычнае пытанне: сколькі запыткаў можа обрабацаваць адна прыменная програма на Node.js, і сколькі экземпляраў сервера патрэбны для падтрымкі певнага обсягу трафіку? Адказ залежыць не толькі ад самай платформы.
Цэль, якой варта прагнуць
Як паведамляецца, платформа для дызайну PicsArt обрабоўвае або-блізу 40 000 запыткаў за секунду, пры чым яе бэкенд у большай частцы складаецца з Node.js.
Этая цыфра вельмі вялікая, і яна залежыць ад многа чыннікаў, кроме самага бэкенд-сервера. Для гэтага аналізу этыя іншы факторы адкладаюцца, і залішаюцца толькі апаратнае і програмнае забезпечэння бэкенду, а таксама сам Node.js.
Што паказваюць сінтэтычныя тэсты
Команда, якая стварыла Fastify, публікавала тэст, па якому Express обрабоўвае або-блізу 15 000 запыткаў за секунду, тады як просты HTTP-модуль Node досягае або-блізу 70 000.
MacBook Pro 15″ 2015 года парадоксальна гэта цыфра. Нават 15 K рэспансоў за секунду у Express здаецца чудовым, але такія тэсты адбываюцца з мініятурным апрацоўшчыкам, які здалека не ўпамінае рэальны API. Тое, што робіць API «рэальным», — гэта даны, спосаб іх перадачы і взаімадзеянне компонентаў, таму рэалістычны апрацоўшчык павінен вярбавацца з базай дадзенаў або іншымі службамі.
Разлік межу «сырым» кодам і Express у будзь-якім разе не ўсё такі важлівы. Усталеныя фрэймворкі, такія як Express, зазвычай ёсць лепшым выборам, таму што ніякая адна інстанцыя на практыцы не зможа обслужыць 100 K запытоў за секунду. Таму для гэтых тэстаў быў установлены Express, пры чым маленькі апрацоўшчык выканаў розныя операцыі.
Апрацоўшчык тэстаў
Апрацоўшчык выканае шасць крокаў:
- Даўжыце новага карыстальніка ў базу дадзенаў.
- Заўзяце 20 карыстальнікаў з базы дадзенаў.
- Фарматаваце і аналізаваце масів з 20 карыстальнікаў.
- Рэкурсыўна пераканвертаваць тыя 20 об’ектаў корыстнікаў у фармат camelCase.
- Сортаваць масів.
- Выконваць простыя вычысленні і задачы, якія выводзяцца на стандартны выхід, напрыклад
Date.nowіconsole.log, якія таксама спрацоўваюць вычысленні.
Размер адпаведзення складаў або-12KB. Кожны об’ект корыстніка мяў розмер 609 байт:
Рэзультат 1: Node.js на Heroku з AWS RDS
Праект быў розмішчаны на Heroku на апаратным забезпечэнні за $25 на месцы, а запыты надсілаліся з максымальной частотай, якая не падвышала сярэжнюю затрымку. Інстанцыя обробіла 31 000 запытоў за 60 секунд, тое ўсьмо 515 запытоў за секунду.
Рэзультат 2: Django на Heroku з AWS RDS
Ёнколі трэба было пазіць, што будзе робіць тэхналогія, якая не ўжо ў однапраменнай працы, у Django быў створаны адпаведны працоўнік за аднаковыя умовы і размешчаны на тым жа серверэ. Рэзультат быў нейкія горшы, чым у Node.js: за 60 секунд было обработана 23 000 запыткаў, тое ўсьмо 389 за секунду.
Рэзультат 3: тры экземпляры Node.js на AWS Elastic Beanstalk
Трэці варыянт апісваў рэальную рэалізацыю ў працэсе вырабоцтва на AWS. База дадзеных і бэкэнд знаходзіліся ў Франкфурцы (eu-central-1) — найбліжэйшым рэгіоне, адстаючым прыблізна на 3 000 км ад тэставальніка. За ўзмацненнем навантажэння працавалі тры экземпляры Node.js. Яны обработалі 19 000 запыткаў за 10 секунд, тое ўсьмо 1 858 запыткаў за секунду. Праз продовжальны тэст навантажэння за 13 хвілін было адправлена 1,5 мільйона успешных запыткаў.
Масштабаванне да 40 000 запыткаў за секунду
Адзін экземпляр можа обрабатваць апоўнач 600 запыткаў за секунду, тады скількі ж будзе патрэбна для 40 000 запыткаў? Прыпустым, што сярэдній канцэнтрык на большай платформе ў два разы моцнейшы за працоўнік для тэстаў. Тады 40 000 / (600 / 2) = 133 экземпляраў, распакаваных па всім свету, для аплікацыі масштабу „унікорна“. Гэта не ўжо такая вялікая проблема.
Моцнейшыя канцэнтрыкі могу быць у тры разы болей вімагаючымі, але кэшаванне і комунікацыя на адной з адбуванняяў можа вярнуць выдатнасць, таму 2 разы — граматычная сярэдняя оцэнка.
Што спамчвае API
Бесліч фактараў можа знізіць швальнасць API. Гэта тыя фактары, якія стосуюцца выдатнасці і зустрэчаюцца ў большасці веб-аплікацый з баку сервера.
Размер дадзенняў
Значэнне колькасці дадзеных, якія зберагаюцца ў базе дадзеных або запрашваюцца з яе, ёсць важлівым, боўша чым у рэляцыйных базах дадзеных, дзе вялікія об’ёмы дадзеных часта выклікаюць складныя запіты або інтэнсіўную працу між СУБД і ўсёй памяці дыска. У будзь-якім случае больша колькасць байтоў значыць большы час перэдачы. Зберагчы файлы ў базе дадзеных — гэта антыпатэрн, таму лепшы варыянт — вікорыстоўванне сістэм зберагчыка об’ектаў. У ідэале рэкорд застаецца ў межах дзесяткаў кілабайт, зазвычай 1–20 КБ.
Адстань да базы дадзеных
Большая адыяцея между бэкэндам і базай з дадзенням значыць дольшы час адправкі запытак і рэзультатаў. Узьмім два бэкэнды: адны ў Вірджыніі, другі ў Франкфурцы, з адной базай з дадзенням у Вірджыніі. Запыт амерыканскага корыстніка доходзіць да бэкэнду ў США за апошнія 10–40 мс, а перадача дадзенняў з бэкэнду да базы займае 1–5 мс. Гэта нормальна. Німецкі корыстнік доходзіць да бэкэнду ў Франкфурцы за 10–20 мс, але запыт да базы ў Вірджыніі займае 120–130 мс. Таму аплікацыя, якая працуе толькі ў аднай рэгіёне, должна трываць дадзеныя і логіку бэкэнду поблізу, а глобальная аплікацыя павінна быць гатовая да складных тэхнічных рашэнняў, каб заставацца шырокай.
Апаратна частка базы з дадзенням
Апаратна частка таксама мае вялікі адзінак. Малая аплікацыя должна купіць крашчую апаратную частку, якая падходзіць да ўровня ўжоўвачання, інакш яе чакаюць тыя ж складныя тэхнічныя рашэнняў.
Канфігурацыя базы з дадзенням
Базы дадзэных прыбываюць з стандартнымі настройкамі, таму іх не трэба додаткова кераваць, але у масштабных сістэмах ім патрэбна увага. Максымальная колькасць з’яўленняў — адна з наяўных настройкаў, якую трэба сочыць. Яна можа стаць прычыной уповольнення працы прыкладнення або перавантажэння сервера базы дадзэных, а бібліятэкі-кліенты, такія як ORM, часта яе зміняюць. Іншая важлівая настройка — час тайма-ауту з’яўленняў.
Колькасць вызоў базы дадзэных
Прыродны API можа выконваць дзесяткі окрэмых вызоў базы дадзэных, каб завершыць заданне, а таксама можа вызываць іншыя сервісы, кожны з якіх таксама выконвае сваі дзесяткі вызоў. Адным з запамятнае прыкладаў быў API банкавага моноліту, які ў серавысі разработкі ў воблаку меў час адпаведзі 9 секунд. Яго апрацоўшчык выканаваў 300 ліній коду, пры чым было адпаведна 30 вызоў базы дадзэных і апошнія 10 вызоў внутраніх сервісаў. Такое часта трапляецца пад час падходу „код спачатку“, а не „дызайн спачатку“.
Рашынкі залежыць ад логікі бізнесу. Чэры і іншыя асінхронныя тэхнікі могу пераносіць частку працы з базы дадзеных у фон, што вымагае разбівання большых сервісаў на маленькія. Адзіненыя запыткі таксама можу зменшыць колькасць вызоў.
Хукі
Популярныя ODM-ы і ORM-ы прысвячаюць хукі або мідлвэр, якія зручныя для обработкі певной логікі. Пад час масовых операцый яны можу стаць скрытым бутлнэкам, адколі плагіны, такія як канвертары camelCase або pascal_case, таксама выкарыстоўваюць вычысленні і час. Хукі дапамагаюць, але тое, што ў яных напісана і дзе, заслуговае на дадзеўныя раздумкі.
Праца, якая сільна навантажвае CPU
Задачы, які вімагаюць значных вычысков CPU, спамоцвячаюць сервер і змушваюць канечнага корыстувальніка чакаць. У Node.js багато з такіх задач павяржаюцца на пул нітак. Хоць гэта не блакуе асінхронныя операцыі I/O, гэта все равно спамоцвячае API. Напрыклад, калі корыстувальнік нажымае кнопку рэўістрацыі, ён чакае, пакуль пул нітак перэтворыць пароль на хэш, на што патрабуецца больш чым 100 мілісекунд.
Проблемы сцыклу зьвярэнняў
Node.js выконвае код у сцыклі зьвярэнняў, на адной нітцы, таму выконавачысць коду вплывае на всю аплікацыю. Функцыі JSON.parse і JSON.stringify могу спамоцвячаць API, а вкладаныя сцыклы і рэкурзыўныя функцыі ўтвараюць аблікансіі. Ігнараванне прыроды работы Node.js можа зробіць аплікацыю недоступной, залежна ад размеру дадзеных і інтэнсівнасці трафіку.
Нескладная праектавання інфраструктуры
Значныя інфраструктуры не толькі маюць больш заўсёды проблем, чым моналітныя сістэмы, але і проблемы іншага характэру, і для ўсіх іх часта патрэбны складныя архітэктурныя рашэнні. Калі ёсць багато складовых, паслабленая архітэктура сутліва паўлінае швальнасць API і робіць сістэму неэфектываюю з точкі зору вікорыстоўвання рэсурсаў, таму плацяцца больш за тое, што могла б коштаць меней. Праектуячы складныя прыкладнікі, трэба думаць пра тыя проблемы, якія рашае тая чы іншая тэхналогія, і знаць альтэрнатывы. Трэба таксама вазьміць у расчыт, як можу змяніцца спектр трэбаванняў за два чы шасць месцаў, і пераканацца, чы кожна рашэнне падходзіць пад гэтыя прыпускі. Таксама важліва ўважна аднесціся да умов службы (SLA) і да нефункцыональных трэбаванняў, укладаючы ў гэта, што можа адбыцца, якшо обсяг трафіку зрасне.
Масштабаванне і налаштаванне складовых
Компаненты, які дадзены да інфраструктуры, могу спамляць работу всей платформы. Возьмем RabbitMQ — у яго, як і ў будзь-якай тэхналогіі, ёсць множыць настаўк. Для пачатку стандартныя настаўкі падходзяць, але пасля дакладнага аналізу конкрэтнага компанента, перагляду настройкі аб іх перэработцы інфраструктура можа значна паспрабаваць. Компаненты таксама павінны масштабавацца разам з выкарыстоўваннем, ўбліжчы не стаўці бутаўкай у працы.