HTTP-кеш
Дата оновлення перекладу 2024-06-07
HTTP-кеш
Природа насичених веб-додатків передбачає, що вони динамісні. Незалежно від того, наскільки ефективний ваш додаток, кожний запит буде містити більше роботи, ніж обслуговування статичного файлу. Зазвичай це нормально, але коли вам потрібно, щоб ваші запити були блискавично швидкими, вам знадобиться HTTP-кешування.
Кешування на плечах титанів
З HTTP-кешуванням ви також можете кешувати сторінки цілком (тобто, відповідь), а потім, в обхід додатку, віддавати кешовані дані для кожного запиту. Звичайно ж, це не завжди можна застосувати для дуже динамічних сайтів. Чи все ж можливо? За допомогою Включень крайніх сторін (ESI) ви можете використати силу HTTP-кешування лише для фрагментів вашого сайту.
Система кешування Symfony відрізняється від інших, так як вона покладається на простоту та потужність HTTP-кешування, як це визначено у специфікації RFC 7234 - Кешування. Замість того, щоб винаходити кешування наново, Symfony користується стандартом, який визначає базові комунікації в мережі. Як тільки ви зрозумієте основні моделі HTTP валідації та закінчення строку кешу, ви будете готові до керування системою кешування Symfony.
Так як HTTP-кешування використовується не лише Symfony, існує безліч статей на дану тему. Якщо ви новачок в HTTP-кешуванні, наполегливо рекомендуємо вам прочитати статтю Райана Томайко Речі, які роблять кеші . Іншим вичерпним джерелом є Туторіал з кешу від Марка Ноттінгема.
Кешування за допомогою кешуючого шлюзу
При HTTP-кешуванні, кеш повністю відокремлений від вашого додатку та розміщується між вашим додатком та клієнтом, що виконує запит.
Робота кешу полягає у прийманні запитів від клієнта та їх передачі вашому додатку. Кеш також отримуватиме відповідь від вашого додатку та перенаправлятиме його клієнту. Кеш є "посередником" у клієнт-серверних комунікаціях між клієнтом та вашим додатком.
На шляху, кеш зберігатиме кожну відповідь, яку вважає "кешованою" (див. Вступ в HTTP-кешування ). Якщо цей же ресурс буде запитаний ще раз, кеш відправить збережену (кешовану) відповідь клієнту, повністю ігноруючи ваш додаток.
Цей тип кешування відомий під назвою "кешуючий шлюз HTTP шлюза". Існує багато кешерів такого типу, наприклад: Varnish, Squid у режимі зворотного проксі, а також зворотний проксі Symfony.
Tip
Кешуючі шлюзи іноді називаються кешами зворотного проксі, сурогатними кешами або навіть HTTP-акселераторами.
Зворотний проксі Symfony
Symfony містить зворотний проксі (також називається кешуючий шлюз), написаний на PHP. Це кеш зворотного кросі з неповним функціоналом на кшталт Varnish , однак це чудовий спосіб почати.
Tip
Щоб дізнатися деталі про налаштування Varnish, див. Як використовувати Varnish для прискорення мого сайту.
Використайте опцію framework.http_cache
, щоб включити проксі для
середовища виробництва :
1 2 3 4
# config/packages/framework.yaml
when@prod:
framework:
http_cache: true
Ядро негайно почне поводитися як зворотний проксі: кешувати відповіді з вашого додатку та повертати їх клієнту.
Проксі має розумну конфігурацію за замовчуванням, але вона може бути тонко налаштована через набір опцій .
У режимі налагодження Symfony автоматично додає заголовок
X-Symfony-Cache
до відповіді. Ви можете також використати опцію конфігурації
trace_level
та встановитти її як none
, short
або full
, щоб додати
цю інформацію.
short
додасть інформацію лише для головного запиту. Вона написана
ємно, тому записувати інформацію у файли логів на вашому сервері легко.
Наприклад, в Apache ви можете використати %{X-Symfony-Cache}o
у
твердженнях формату LogFormat
. Ця інформація може бути використана
для вилучення загальної інформації про ефективність кешу ваших маршрутів.
Tip
Ви можете змінити імʼя заголовку, використовуваного для інформації
інформації трасування, використовуючи опцію конфігурації trace_header
.
Робимо ваші відповіді HTTP-кешованими
Як тільки ви додасте кеш зворотного проксі (наприклад, як зворотний проксі Symfony або Varnish), ви готові кшеувати ваші відповіді. Щоб зробити це, вам потрібно повідомити вашому кешу, які відповіді є кешованими і на який час. Це робиться шляхом установки заголовків кешу у відповіді.
HTTP визначає чотири заголовки відповідей кешу, які ви можете активувати:
Cache-Control
Expires
ETag
Last-Modified
Ці чотири заголовки використовуються для того, щоб допомогти вам кешувати ваші відповіді за допомогою двох різних моделей:
- Кешування закінчення строку дії Використовується, щоб кешувати всю вашу відповідь на визначену кількість часу (наприклад, 24 години). Просто, але девалідація кешу складніша.
- Кешування валідації Складніша модель: використовується, щоб кешувати вашу відповідь, але дозволяє вамм динамічно інвалідувати її, як тільки ваш контент зміниться.
Кешування строку дії
Найпростіший спосіб кешувати відповідь - це кешувати її на певну кількість часу:
1 2 3 4 5 6 7 8 9
// src/Controller/BlogController.php
use Symfony\Component\HttpKernel\Attribute\Cache;
// ...
#[Cache(public: true, maxage: 3600, mustRevalidate: true)]
public function index(): Response
{
return $this->render('blog/index.html.twig', []);
}
Завдяки цьому новому коду, ваша HTTP-відповідь матиме наступний заголовок:
1
Cache-Control: public, s-maxage=3600, must-revalidate
Він повідомляє вашому зворотному проксі HTTP кешувати цю відповідь на 3600 секунд.
Якщо хтось запитає цей URL знову раніше, ніж через 3600 секунд, ваш додаток взагалі
не буде задіяний. Якщо ви використовуєте зворотний проксі Symfony, подивіться на
заголовок X-Symfony-Cache
для налагодження інформації про успіхи та невдачі кешу.
Tip
URI запиту використовується в якості ключа кешу (хіба що ви не варіюєте).
Це дуже продуктивно та легко використовувати. Однак девалідація кешу не підтримується. Якщо ваш контент зміниться, вам потрібно буде зачекати доти, доки строк дії вашого кешу не закінчиться, щоб сторінка оновилася.
Tip
Насправді, ви можете вручну інвалідувати ваш кеш, але це не є частиною специфікації HTTP-кешування. Див. Девалідація HTTP-кешу .
Якщо вам потрібно встановити заголовки кешу для багатьох різних дій контролера, подивіться на FOSHttpCacheBundle. Він надає спосіб визначати заголовки кешу, засновуючись на зразку URL та інших властивостях запиту.
Врешті-решт, для більш детальної інформації про закінчення строку дії кешу, див. Закінчення строку дії HTTP-кешу.
Кешування валідації
З кешуванням закінчення строку дії, вам просто потрібно сказати "кешувати протягом 3600 секунд!". Але коли хтось оновлює кешований зміст, ви не зможете побачити його до тих пір, поки не закінчиться строк дії кешу.
Якщо вам потрібно побачити оновлений зміст одразу ж, вам потрібно або інвалідувати ваш кеш, або викристати модель кешування валідації.
Щоб дізнатися більше, див.. Валідація HTTP-кешу.
Безпечні методи: Кешування лише запитів GET або HEAD
HTTP-кешування працює тільки для "безпечних" HTTP-методів (таких як GET і HEAD). Це означає:
- Не намагайтесь кешувати запити PUT або DELETE. Це не спрацює, і з гарної причини. Ці методи не повинні бути використані при зміні стану вашого додатку (наприклад, видаленні поста блогу). Їх кешування буде запобігати попадання деяких запитів або їх зміні вашого додатку.
- Запити POST зазвичай вважаються некешованими, але їх можна кешувати, якщо вони містять ясну інформацію свіжості. Однак, кешування POST не реалізується широко, тому вам варто цього уникати за можливості.
- Вам ніколи не варто змінювати стан вашого додатку (наприклад, оновлювати пост блогу) під час відповіді на запит GET або HEAD. Якщо ці запити будуть кешовані, майбутні запити можуть ніколи не потрапити на ваш сервер.
Більше методів відповіді
Клас Відповідь містить також багато інших методів, що відносяться до кешу. Ось найкорисніші з низ:
1 2 3 4 5
// відмічає відповідь як "прострочену"
$response->expire();
// форсує повернення відповіді 304 без змісту
$response->setNotModified();
На додаток до цього, всі основні HTTP-заголовки, що відносяться до кешу, можуть бути встановлені за допомогою одного методу setCache():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// використайте цей метод, щоб встановити декілька налаштувань кешування в одному виклику
// (цей приклад перелічує всі доступні налашштування кешу)
$response->setCache([
'must_revalidate' => false,
'no_cache' => false,
'no_store' => false,
'no_transform' => false,
'public' => true,
'private' => false,
'proxy_revalidate' => false,
'max_age' => 600,
's_maxage' => 600,
'immutable' => true,
'last_modified' => new \DateTime(),
'etag' => 'abcdef'
]);
Tip
Всі ці опції також доступні при використанні атрибуту #[Cache()]
.
Інвалідація кешу
Інвалідація кешу не є частиною HTTP-специфікації. Однак, вона може бути дуже корисною для видалення різнх записів HTTP-кешу, як тільки будь-який зміст вашого сайту оновлюється.
Щоб дізнатися більше, див. Інвалідація кешу.
Використання Включень крайніх сторін (ESI)
Коли на сторінці присутні динамічні частини, вам не вдатсться кешувати цілі сторінки, а доведеться робити це частинами. Читайте Робота з включеннями крайніх сторін, щоб дізнатися, як сконфігурувати різні стратегії кешування для певних частин вашої сторінки.
HTTP-кешування та сесії користувача
Коли сесія розпочинається під час запиту, Symfony перетворює відповідь на приватну некешовану відповідь. Це найкраща поведінка за замовчуванням, щоб не кешувати особисту інформацію користувача (наприклад, корзину покупок, деталі профілю користувача і т.д.) і не оголити її іншим відвідувачам.
Однак, навіть запити, що отримують переваги від сесії, можна кешувати за деяких обставин. Наприклад, інформація, повʼязана з якоюсь групою користувачів має кешуватися для всіх користувачів, що належать до цієї групи. Обробка таких просунутих сценаріїв кешування знаходиться поза межами Symfony, але вони можуть бути вирішені за допомогою FOSHttpCacheBundle.
Для того, щоб відключити поведінку Symfony за замовчуванням, яка робить запити, що використовують сесію, некешованими, додайте наступний внутрішній заголовок до вашої відповіді, і Symfony не буде її змінювати:
1 2 3
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
Висновок
Symfony створена таким чином, щоб дотримуватися перевірених "правил дорожнього руху" в HTTP. Кешування - не виключення. Опанування системи кешування Symfony передбачає близьке знайомство з моделями кешування HTTP та їх ефективне використання. Це озанчає, що замість того, щоб покладатися лише на документацію Symfony та приклади коду, ви отримуєте доступ до цілого світу знань, що відносяться до кешування в HTTP та кешуючих шлюзів, таких як Varnish.