Увеличиваем RPS на Nuxt.js

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Все мы знаем что nuxt.js 2 (да и любое node.js приложение с SSR) не держит нагрузку без кеша, в среднем проекте если включить режим SSR то будет держать 20-30 RPS что очень мало.

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

Есть 3 проблемы с которыми я сталкивался на проекте, и хотел бы стабилизировать ситуацию. Чтобы дать еще один шанс запуститься приложению хотя бы без SSR.

  1. Медленные ответы API, бывает что бэк что-то не предусмотрел и на проде запросы стали медленными.

  2. Ошибки JS в режиме SSR, причем в браузере этих ошибок нет. Допустили по неосторожности или другим причинам.

  3. Большая нагрузка при DDOS когда упираемся в оперативку или процессор, надо отключать режим SSR и дать клиенту пустышку чтобы в браузере могло запуститься.

Пообщавшись в девопсами пришли к некоторым правилам которым должно следовать SPA приложение:

  • Отключить SSR при медленном рендере страницы. Делегировать рендер браузеру.

  • Даунгрейд должен быть не во всем СПА, а только там где есть проблема.

  • В случае больших нагрузок и когда рендер всё медленнее и медленнее надо следить за этим, и на время отключить SSR во всём приложении, спустя время в автоматическом режиме включать снова.

  • Отключать SSR принудительно на некоторых страницах где он не нужен, чтобы не грузить сервер.

  • Добавить кеш и storage держать в redis

Написал в общем модуль который всё это делает в автоматическом режиме. Для достижения максимального эффекта надо еще добавить модуль кеширования (например nuxt-ssr-cache).

npm install @drozd/nuxt-performance

Далее идём в nuxt.config.js

module.exports = {
  performance: {
    // логирование времени запросов
    renderRouteTimeCallback: (route, ms) => {
      console.log(`time render route: ${route} ${ms} ms`);
    },
    // отключаем SSR на нужных нам роутах
    isOnlySPA: (route, _context) => {
      return route === '/personal';
    },
    // кол-во допустимых мс для рендера при SSR
    maxRenderTime: 1000,
    // кол-во попыток отрисовать SSR если рендер медленный, 
    // дальше выключаем на указнное время timeDisabledSsrWithRoute
    maxAttemptSsr: 5,
    // RegExp страниц исключения для модуля в целом
    excludeRoutes: /healthcheck/, 
    // на какое время выключаем сср для страницы
    timeDisabledSsrWithRoute: 1000 * 60, 
    // интервал очистки общего счётчика, когда выключили SSR на всём сайте
    clearSlowCounterIntervalTime: 1000 * 60 * 5, 
    // Общее кол-во медленных запросов на сайте, потом отключаем SSR везде 
    maxSlowCount: 50
  }

  // ...
};

После внедрения данного модуля и настройке кеширования всех страниц на 10сек мы получили прирост RPS в ~15раз, с 30 до 500 результат плавающий, зависит от выделенных ресурсов админами :)

Репозиторий https://github.com/gustoase/nuxt-performance

Если у вас есть опыт по оптимизациям, пишите, всем будет полезно)

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Сколько в среднем держит ваш SPA
0% 10-30 0
50% 30-50 1
0% 50-100 0
50% 100-300 1
0% 300 — 9999 0
Проголосовали 2 пользователя. Воздержался 1 пользователь.
Источник: https://habr.com/ru/post/688858/


Интересные статьи

Интересные статьи

Доброго времени суток, хабровчане!В данной статье я рассмотрю вопрос развертывания с нуля NuxtJS-проекта (либо любого другого проекта на NodeJS) на VDS-сервере с использо...
Одна из самых важных (на мой взгляд) функций в Битрикс24 это бизнес-процессы. Теоретически они позволяют вам полностью избавиться от бумажных служебок и перенести их в эл...
Есть статьи о недостатках Битрикса, которые написаны программистами. Недостатки, описанные в них рядовому пользователю безразличны, ведь он не собирается ничего программировать.
Согласно многочисленным исследованиям поведения пользователей на сайте, порядка 25% посетителей покидают ресурс, если страница грузится более 4 секунд.