Статьи

Кэширование страниц по HTTP

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

Кэширование страниц в Rails записывает результат ваших действий на диск, и ваш http-сервер может выполнить следующий запрос. Это прекрасно работает, но есть несколько вещей, которые могут вызвать некоторые проблемы:

  1. Кеш страниц записывает на диск, поэтому если у вас есть несколько серверов, которые вы хотите защитить за общим слоем кеша, вам придется проделать дополнительную работу.
  2. Кэш страницы, поскольку он записывает данные непосредственно на диск, не поддерживает истечение срока действия кэша.
  3. Диски, как правило, работают медленно, возможно, кэширование в память будет больше выдавливать из ваших серверов?

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

Кэши на основе стандартов также реализованы во многих клиентах — это означает, что ресурсы, которые мы пометили как кэшированные, также могут кэшироваться в браузере. Это экономит нам не только дополнительные ресурсы БД и ЦП при рендеринге новой страницы, но и реальную пропускную способность запроса.

Типы HTTP-кэша

Самый простой кэш для реализации — это кэш, основанный на времени, например, Expires или max-age . Когда мы создаем наш ответ, мы устанавливаем заголовок кеша, который говорит «истекай через 3 часа» или «истекай в 15:00». Использование метода ActionController expires_in позволит вам установить соответствующие заголовки для истечения времени. Вы захотите избежать ошибок кэширования, поэтому лучше всего выполнить настройку заголовка в фильтре после, который не будет вызываться, если ваше приложение 500.

class PostsController < ActionController::Base
after_filter :set_http_cache, :only => :index
private
def set_http_cache
expires_in(30.seconds, :public => true)
end
end

Мы также можем более разумно кэшировать, используя last-modified etag и etag . После первого запроса клиент отправит обратно токены last-modified и etag (возможно, оба). Работа приложения заключается в том, чтобы определить, можем ли мы отправить пустой ответ обратно (и, следовательно, использовать кэшированный ресурс), или нам следует снова извлечь нашу страницу и использовать ее.

class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
if stale?(:last_modified => @post.updated_at.utc, :etag => @post)
#Render your post page
end
end
end

view raw
gistfile1.rb
hosted with ❤ by GitHub

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

Более умные люди, чем я , назвали эти два стиля кэширования «сильными» и «слабыми». «Сильные» кэши — основанный на времени срок действия — способны обслуживать запросы без какого-либо условного получения, в то время как «слабые» кэши не могут.

На сайтах с высоким трафиком, скажем, более 1000 запросов в минуту, с контентом, который не может быстро устареть, мне нравится использовать микро-кеши. Микро-кэш — это expires_in кэш в стиле expires_in с очень коротким сроком службы. Промежуток времени в минуту позволяет вам значительно снизить нагрузку на вашу систему (с 1000 / req / m до 1 / req / m), сохраняя при этом ваш контент свежим и свежим.

Итак, теперь, когда мы настроили тот тип кэша, который наиболее полезен для нашего приложения, пришло время еще больше усилить наш уровень кэширования. Если оставить все как есть, мы будем кэшировать запросы для каждого пользователя, а не глобально. Для глобального кеша мы хотим реализовать какой-то кеш, который находится между нашим HTTP-сервером и нашим Rails-приложением.

Rack :: Cache

Rack :: Cache , как я надеюсь, вы можете догадаться, является небольшим промежуточным программным обеспечением для стойки, которое находится прямо перед вашим Rails-приложением. Ответы Rails с правильными заголовками будут храниться в любом выбранном вами совместимом с Rack :: Cache хранилище (память процесса, файлы, memcache, redis) и, если придет следующий запрос, будут возвращены прямо из этого хранилища без каких-либо накладных расходов Rails. ,

Rack :: Cache устанавливается вместе с Rails 3 и очень прост в настройке — просто убедитесь, что он вам нужен, и вы готовы к работе. Скорее всего, вы найдете лучшие показатели производительности, если измените настройку для сущности и мета-хранилища по умолчанию. Metastore имеет небольшой размер и проверяется при каждом запросе, в нем хранятся сведения о запросе, включая значения заголовков. В хранилище памяти, или даже что-то вроде Redis или Memecached, Metastore — хороший выбор здесь.

Хранилище сущностей — это фактическое хранилище ваших кэшированных страниц. Он доступен только при попадании в кэш и содержит значительно большую полезную нагрузку. Хранилища данных, такие как хранилище файлов, становятся пригодными для использования здесь, но лично я бы добавил их в Memcached или Redis и покончил с этим.

Дополнительные параметры кэширования

Rack :: Cache, безусловно, крутой и простой в настройке, но, будучи рубином, это не будет вашим самым быстрым выбором. К счастью, есть много других вариантов для подающего надежды кэшера.

Принимая во внимание, что Rack :: Cache находится за вашим сервером (возможно, Nginx или Apache), но, по крайней мере, концептуально, перед кодом вашего приложения, прокси-сервер находится перед сервером, молча пересылая запросы.
Одним из самых известных кеширующих прокси-серверов является фантастически названный лак . Существует множество настроек и настроек, которые вы можете использовать для лакирования, чтобы заставить его вести себя по-разному, но, возможно, это выходит за рамки этой статьи, чтобы углубиться в каждый закоулок.

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

backend facebookforcats {
.host = «localhost»;
.port = «3000»;
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

Это говорит лаку, что вы будете запускать кеш для facebookforcats (вы ожидаете много трафика) на порту 3000 локально. Обязательно запустите приложение на порте, который не равен 80. Чтобы запустить кэш:

varnishd -a :80 -f catalyst.vcl -s file,/var/cache/varnish.cache,1024M

Это заставляет лака запускаться, прослушивая порт 80, используя конфигурационный файл Catalyst и создать кеш-файл /var/cache/varnish.cache размером не более 1 ГБ.

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