Все мы знаем что nuxt.js 2 (да и любое node.js приложение с SSR) не держит нагрузку без кеша, в среднем проекте если включить режим SSR то будет держать 20-30 RPS что очень мало.
Стандартные решения это подключить пару пакетов каких нибудь кешеров, и кешировать каждую страницу или запросы. В целом это хорошо помогает.
Есть 3 проблемы с которыми я сталкивался на проекте, и хотел бы стабилизировать ситуацию. Чтобы дать еще один шанс запуститься приложению хотя бы без SSR.
Медленные ответы API, бывает что бэк что-то не предусмотрел и на проде запросы стали медленными.
Ошибки JS в режиме SSR, причем в браузере этих ошибок нет. Допустили по неосторожности или другим причинам.
Большая нагрузка при 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
Если у вас есть опыт по оптимизациям, пишите, всем будет полезно)
