понедельник, 5 ноября 2012 г.

Антикэш на хэшах ресурсов: Вступление

Преамбула:
  • Есть некое приложение, которое в ходе своей работы использует множество внешних ресурсов/файлов;
  • Приложение работает в среде интернет-браузера;
  • Всего внешних ресурсов/файлов более 3000 единиц;
  • От релиза к релизу часть этих ресурсов может изменятся (например, художник перерисовал изображения некоторых айтемов или фоновых изображений, добавлены новые строковые, нормализованы по уровню громкости фоновые звуки, и прочее).

Итоговый алгоритм определения "протухшего" ресурса в кэше браузера определяется связкой "интернет-браузер + файловый сервер".
Подробнее о кэшировании можно почитать тут или воспользоватся результатами поиска.

Данная тема затронута в докладе на встрече RAFPUG, прошедшей в мае этого года в г.Челябинске (см. презентацию).

Проблема:
Алгоритм определения факта "протухания" файла в кэше браузера напрямую зависит от самого браузера и настроек отдающего файлового сервера.

Для уверенности в том, что клиентское приложение загрузит последнюю версию ресурса, необходимо принудительно сбросить кэш для всех ресурсов.
Сброс кэша осуществлялся добавлением в конец URL ресурса случайного параметра, например:
http://mysite.ru/images/bg.png?<random string>
Зачастую в качестве рандомного параметра используется номер версии приложения.

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

Следовательно, требуется добиться следующих результатов:
  1. Уверенность в том, что клиентское приложение будет использовать последнюю версию ресурса;
  2. Независимость от алгоритма поиска ресурса в кэше браузера;
  3. Снижение нагрузки на отдающий файловый сервер.

Решение:
Способ №1:
  1. Сформировать словарь соответствий относительных URL файлов с их хэшами, например: файлу
    ./images/bg.png
    соответствует хэш
    bb74f737c85c996cc2ec29c63698bf80
  2. Использовать в качестве антикэш-параметра значение хэша из словаря при формировании URL для загрузки файла, например:
    http://mysite.ru/images/bg.png?bb74f737c85c996cc2ec29c63698bf80
    Если соответствия не найдено — использовать строку с номером последней версии приложения.

Способ №2:
Данный способ был подсказан Михаилом Антипиным (Nox Noctis), за что ему огромное чистосердечное спасибо.
  1. Сформировать словарь соответствий оригинальных имен файлов с их новыми именами, например: оригинальному имени файла
    bg.png
    соответствует новое имя
    00240736ec53d1f23366122e8d12db5f9f06f7c70404000304d8c000
    В новое имя файла может быть "зашит" не только его хэш, но и дополнительные данные, например: размер файла в байтах, тип (png, jpg, ...), дату последнего изменения и прочее.
  2. Переименовать файлы в соответствии со словарем и переместить в общую для внешних ресурсов папку, например:
    http://mysite.ru/files/
  3. Определять его новое имя файла при формировании URL, по оригинальному имени используя словарь, например:
    http://mysite.ru/files/00240736ec53d1f23366122e8d12db5f9f06f7c70404000304d8c000

P.S.: Оба решения успешно протеситрованны и используются в боевых условиях.
В дальнейшем в данном посте будут размещены ссылки на описания реализаций каждого способа, а так же рассмотрены преимущества и недостатки каждого из них.