Повысьте производительность и скорость вашего веб-приложения Rails, обслуживая и кэшируя статический контент.

В моем предыдущем посте я представил три различных метода совместного использования статического содержимого приложений Rails (это также применимо к любому веб-приложению, которое должно обслуживать статический контент) с обратным прокси-сервером Nginx.

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

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

Что такое кеширование?

Кэширование - это процесс локального хранения копии ответов для ускорения связи и доставки контента конечному пользователю. Копия ответов может храниться на стороне клиента (в браузере) или на стороне сервера. Кэширование - это мощный метод обслуживания повторяющихся запросов статического содержимого, такого как изображения или таблицы стилей. Чтобы проиллюстрировать больше, в данном случае клиент запросил загрузку изображения. Если изображения нет в кеше, запрос будет перенаправлен в серверное приложение. Однако, если он находится в кеше, запрос будет обслуживаться из кеша, и запрос не попадет в серверное приложение.

Чем может помочь кеширование Nginx

В производственных средах приложения Rails и другие веб-приложения обычно размещаются за обратным прокси-сервером, таким как Nginx или Apache. Обратные прокси-серверы - это приложения, которые предназначены для обслуживания огромного количества одновременных запросов и защиты внутренних приложений. Обратный прокси-сервер будет перенаправлять запросы бэкэнд-приложению, и как только он получит ответ, он будет перенаправлен клиенту.

Отправка каждого запроса в серверное приложение может повлиять на скорость и производительность внутреннего приложения. Следовательно, настройка обратного прокси-сервера для хранения локальной копии (кеша) статических файлов и их обслуживания без участия серверного приложения может улучшить производительность приложения.

Как реализовать кеширование Nginx

Прежде чем переходить к конфигурациям Nginx, мы должны убедиться, что развернутое приложение Rails имеет копию предварительно скомпилированных ресурсов и настроено для обслуживания статических ресурсов. Первую задачу можно выполнить, включив следующую строку в файл Dockerfile приложения.

bundle exec rake assets:precompile

Настройка приложения Rails для обслуживания статических ресурсов также является простой задачей; нам нужно только убедиться, что указанная ниже переменная среды установлена ​​в работающем контейнере.

RAILS_SERVE_STATIC_FILES: 'true'

« ngx_http_proxy_module - это встроенный модуль Nginx, который позволяет передавать запросы от Nginx к другому серверу. В нашем случае другой сервер - это приложение Rails. Этот модуль предоставляет сложные элементы конфигурации для настройки кеширования для вышестоящих серверов Nginx. В приведенном ниже фрагменте показан полный файл конфигурации Nginx, который используется для кеширования статического содержимого приложения Rails.

Первое, что можно заметить в приведенных выше конфигурациях, - это директиваproxy_cache_path. Эта директива используется для установки следующих конфигураций кеша:

  • Расположение файлов кеша. Данные кеша хранятся в файлах, а функция MD5 используется для именования файлов кеша.
  • Параметр levels определяет уровни иерархии кеша от 1 до 3; каждый уровень принимает значения 1 или 2.
  • keys_zone=blog:10m определяет имя кеша и размер области памяти, в которой будут храниться ключи и информация метаданных.
  • max_size=1g указывает максимальный размер хранилища, которое NGINX может использовать для кеша.
  • inactive=60m указывает максимальное время жизни кеш-объектов кеш-объектов.

proxy_cache_key - вторая используемая директива. Этот элемент должен быть уникальным для каждого из кэшированных запросов, и он будет использоваться для генерации имен файлов кеша.

Затем конфигурации Nginx определяют два местоположения. Первый будет использоваться для обслуживания статических ресурсов, где кеш включен, а другой - для обслуживания динамического контента, где кеш отключен.

location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
  set $skip_cache 0;
  try_files $uri @rails;
  break;
}
location / {
  set $skip_cache 1;
  try_files $uri @rails;
}

Последний шаг - включить кеш для запросов, пересылаемых в приложение Rails. Ниже приводится краткое описание наиболее важных конфигураций, необходимых для выполнения этой задачи:

  • proxy_cache: определяет используемую зону кэш-памяти.
  • proxy_cache_valid: определяет время кэширования веб-ответов.
  • proxy_cache_bypass: определяет условия, при которых запрос не будет взят из кеша.
  • proxy_no_cache: определяет условия, при которых ответ не будет сохранен в кеш.
  • add_header X-Cache-Stats: Добавьте заголовок к ответу, который указывает, было ли запрос попаданием в кеш или промахом в кэше.

Тестирование и проверка конфигураций кеширования

Первое, что я хотел бы проверить, - работают ли конфигурации кеша должным образом или нет. Чтобы проверить это, я несколько раз запросил один и тот же статический файл и проверил заголовок ответа X-Cache-Stats, чтобы проверить, был ли запрос HIT или MISS. На изображении ниже показаны результаты моих запросов, а также показано, что только первый запрос был НЕПРАВИЛЬНЫМ; остальные запросы были HIT.

Следующее, что я хотел бы протестировать и измерить производительность, - это веб-приложение с функцией кэширования и без нее. Для решения этой задачи я реализовал два сервера Nginx, один с функцией кеширования, а другой без нее. Затем я использовал инструмент «бум», чтобы создать несколько одновременных запросов на каждом из серверов. Ниже приведены результаты обоих случаев:

Основываясь на приведенном выше тесте, мы можем сказать, что функция кэширования помогла сократить время, необходимое для выполнения всех запросов, на пять секунд. Кроме того, мы видим, что количество запросов в секунду (RPS) было увеличено с 83 до 98 запросов.

Заключение

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