кэширование JSON: Apache, PHP, jQuery - PullRequest
2 голосов
/ 17 февраля 2012

Я пытаюсь кэшировать контент JSON, сгенерированный php-скриптом из базы данных.Однако набор данных очень стабилен, изменений или дополнений очень мало.Значения данных могут оставаться неизменными в течение нескольких недель.Проблема в том, что он содержит столбец LOB, и для его загрузки требуется заметное время, больше по сравнению с предоставлением json из текстового файла, что означает, что git - это реальный вызов базы данных, который делает его медленным.

Я отображаю данные в таблице с разбивкой на страницы (плагин datatables jquery), и для каждого изменения страницы данные снова выбираются из базы данных, также при переходе на предыдущую страницу.

Я пробовал следующее:

"beforeSend": function (request)
{
    request.setRequestHeader("cache-control", "max-age=86400");
},

Не работает.

Я пытался mod_expires:

ExpiresActive On
ExpiresDefault "access plus 4 hours"
ExpiresByType application/javascript "access plus 1 day"
ExpiresByType application/json "access plus 1 day"

Не работает.

Поэтому яПредположим, что все эти настройки предназначены только для реальных файлов в файловой системе, а не для динамически генерируемых файлов?

Я бы предпочел настраиваемый подход, подразумевающий использование Apache / PHP, поскольку у меня не будет полного контроля над сервером.

РЕДАКТИРОВАТЬ ПЕРЕД ПЕРВЫМ ОТВЕТОМ:

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

РЕДАКТИРОВАТЬ 2:

Разработка и прод.Windows ... так что memcached - это не вариант ...

РЕДАКТИРОВАТЬ 3:

Я пробовал решение для kristovaher, но оно не работает.Заголовки кэша не находятся в ответе все время, и после некоторой обработки я считаю, что определил проблему: я должен использовать проверку подлинности NTLM, и при выполнении 2 запросов вскоре после друг друга все работает нормально, однако, если вы немного подождетеПохоже, что пользователь прошел повторную проверку подлинности, а затем заголовок элемента управления кэшем «потерян».

Ответы [ 2 ]

3 голосов
/ 17 февраля 2012

Cache-control - заголовок ответа.(edit: На самом деле это также заголовок запроса. Спасибо за Gumbo за указание на него.) Вам нужно добавить такие заголовки в ответ (данные, которые отправляет PHP).

<?php
// How long my cache should last
$cacheDuration=300; // in seconds
// Client is told to cache these results for set duration
header('Cache-Control: public,max-age='.$cacheDuration.',must-revalidate');
header('Expires: '.gmdate('D, d M Y H:i:s',($_SERVER['REQUEST_TIME']+$cacheDuration)).' GMT');
header('Last-modified: '.gmdate('D, d M Y H:i:s',$_SERVER['REQUEST_TIME']).' GMT');

// Pragma header removed should the server happen to set it automatically
// Pragma headers can make browser misbehave and still ask data from server
header_remove('Pragma');
?>

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

  • Вы генерируете свой JSON, каким бы он ни был.
  • Вы сохраняете этот JSON в своей файловой системе как временный файл.
  • Вы отправляете содержимое клиенту с заголовками Cache-control, заставляя браузер больше не запрашивать данные с сервера и вместо этого использовать кеш.
  • Если на сайт заходит другой пользователь, а его браузер этого не делаетесли у вас есть этот кеш, ваш скрипт должен проверить, существует ли файл кеша (созданный вами в пункте 2), если он существует, вы читаете данные для клиента из этого файла, а не генерируете их снова.
  • Вам также следуетпроверьте, сколько лет файлу кеша, возможно, генерируйте файл снова каждые несколько дней.

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

РЕДАКТИРОВАТЬ:

Пример в реальном времени здесь: http://waher.net/cachetest.php (тот же код, что показан выше).

Этот файл загружается браузером из кэша в течение 5 минут.Но обратите внимание, что если вы обновите страницу, она игнорирует кеш браузера и по-прежнему отправляет запрос на сервер.Вы можете попробовать его лучше, если откроете новую вкладку вместо обновления страницы и введите URL, а Firebug / Chrome Dev Tools покажет, что файл был загружен из кэша.

1 голос
/ 23 февраля 2012

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

В любом случае, мое решение было использовать APC:

http://www.php.net/manual/en/book.apc.php

Я использую windows, соответствующие двоичные файлы можно найти здесь:

http://downloads.php.net/pierre/

какая зависит от вашей версии PHP и как она была скомпилирована (с vc6 или vc9). Файл php_apc.dll нужно будет поместить в каталог расширений php, и вам нужно будет добавить строку

extension=php_apc.dll 

к php.ini

Тогда вы в основном делаете:

if (apc_exists($key)){
   return apc_fetch($key);
}
// get data from database because it was not in the cache
//...
//add data to cache
apc_add($key, $result);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...