Все мы знаем что 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
Если у вас есть опыт по оптимизациям, пишите, всем будет полезно)