PHP: кэширование страниц с состоянием - PullRequest
5 голосов
/ 20 февраля 2010

Я хотел бы использовать кэширование на паре страниц:

  1. отдельных страниц блога
  2. index.php

Однако после разработки моей системыЯ понял, что заголовки моих страниц меняются в зависимости от состояния очень слабо (иначе, это говорит что-то вроде «Здравствуйте, johnnie@example.com», если вы вошли в систему).Поэтому я хочу убедиться, что он не отображает неверное имя пользователя или адрес электронной почты вверху.

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

Как мне обойти это?

Ответы [ 7 ]

8 голосов
/ 20 февраля 2010

Вы захотите подумать, ПОЧЕМУ вы хотите заняться кэшированием. Кэширование - это оптимизация, поэтому его следует выполнять только при необходимости.

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

Если вы уверены, что это необходимо, тогда вы будете знать, сколько улучшений вам нужно. Вы можете рассмотреть кэширование только ЧАСТЕЙ страниц - это будет менее эффективно на внешнем и кэширующем уровнях, чем кэширование полных страниц, но может потребовать больше нагрузки на серверную часть, поскольку вы получите более высокую частоту обращений в кэш.

Рассмотрим страницу, которая имеет персонализированный элемент (скажем, Hello Johnnie) и часть, которая является дорогостоящей для вычисления, но изменяется относительно редко и одинакова для всех пользователей - скажем, некоторые цены на акции.

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

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

4 голосов
/ 20 февраля 2010

Возможность, которую я использовал пару раз:

  • сгенерируйте страницу и сохраните ее в кеше, содержащем что-то вроде "Hello, %%PLACEHOLDER_NAME%%" вместо настоящего имени.
  • когда пользователь загружает страницу:
    • загрузить кэшированную страницу
    • сделать (быстро) str_replace, чтобы заменить тег %%PLACEHOLDER_NAME%% именем пользователя
    • отправить "частично динамическую" страницу, которую вы создали таким образом.

Это означает, что вам придется выполнять некоторые манипуляции с PHP, и вы не сможете кэшировать всю страницу и не служить ей как статический файл ...

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

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


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

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

2 голосов
/ 20 февраля 2010

Вы можете использовать пользовательские параметры в качестве Cache_ID или Cache_ID_Key, используемых в большинстве библиотек кэша:

пример:

$id = sh1($userMail);
$cache->save($id);

Это минимальный пример. Идея заключается в том, что «ключ должен включать информацию, специфичную для пользователя», которая уникальна для каждого пользователя.

Надеюсь, вы поняли идею.

1 голос
/ 20 февраля 2010

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

echo "Hello ".$_SESSION['username'];
1 голос
/ 20 февраля 2010

Честно говоря, это, вероятно, излишне для того, что вы хотите, но ESI решает проблемы, с которыми вы сталкиваетесь.

Тем не менее, вы также можете подумать об этом: сколько вашего трафика зарегистрировано? Для многих веб-приложений более 90% трафика является анонимным, и все анонимные страницы отображаются одинаково. Простое кэширование анонимных страниц может принести вам много пользы, которую вы ищете, без особой работы.

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

1 голос
/ 20 февраля 2010

Где вы хотите кешировать?

На вашем сервере? Возможно, вы захотите взглянуть на Smarty.

На прокси / клиентах? Затем сделайте кэшируемую html-страницу, замените любой динамический контент пустыми divами и запишите значения с использованием javascript - javascript может кэшировать некоторую информацию в файлах cookie и вернуться на сервер для остальных.

Или посмотрите заголовок 'Varies: Cookie', чтобы узнать, как сделать кэширование, ориентированное на сеанс.

С

1 голос
/ 20 февраля 2010

Какой шаблонизатор вы используете? Smarty? если это так, то вы можете заставить не кэшировать некоторые динамические части веб-страницы, такие как

{nocache}
Hello {$username} This is your Email {$email}
{/nocache}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...