Если на Вашем сайте практически нет динамики, то Вы легко можете складывать все его страницы в кэш и практически не делать запросов к бекенду. Но что делать если на сайте есть персонализированные данные (авторизация, блок пользователя, баннера)?
ESI позволяет разбить страницу на логические части, а при обработке страницы делать дополнительные запросы для получения содержимого этих частей. Все выглядит довольно просто:
Всем привет!
Всем пока!!!
Web-сервер, поддерживающий ESI вызовы, просто сделает дополнительный запрос, а результат вставит на место ESI инструкции. Допустим наш скрипт “news.php” содержит такой код:
echo "
</ul>”;
После обработки первого примера, Web сервер вернет клиенту такую страницу:
Всем привет!
Всем пока!!!
Запросы ESI можно кэшировать. Следовательно, у Вас появляется удобное средство работы с динамическим контентом. Достаточно разделить их на разные блоки и закэшировать те, которые не изменяются (либо изменяются редко).
[ad]
Web сервер, который поддерживает ESI, делает запрос к бекенду (в нашем случае, PHP). Далее получив страницу, обрабатывает все ESI вызовы, делая на каждый из них дополнительный запрос для получения содержимого. Далее складывает (или не складывает) все это в кэш и генерирует страницу. Для последующих вызовов Web сервер будет получать данные из кэша и не делать дополнительных ESI запросов.
Самая сложная задача – это кэширование блоков, которые уникальны для каждого пользователя. Например, блок с персональными ссылками на профиль, настройки и превью фотки. В это случае, блок придется сохранять в кэш для каждого пользователя.
Стоит учитывать, что количество таких блоков в кэше будет пропорционально количеству пользователей.
общее количество = количество пользователей х количество блоков на страницу
Пусть у нас есть сайт с новостями. Новости обновляются каждый час. На сайте также есть блок авторизации и ссылки для авторизированных пользователей. Выделяем такие блоки для ESI:
## Все скрипты для ESI вызовов будут находиться в папке app
<? if ( $user ) { ?>
Привет, <? } else { ?>
<? } ?>
<? session_start(); ?>
<? } ?>
$rss = file_get_contents(‘http://feeds.nytimes.com/nyt/rss/HomePage’);
$xml = simplexml_load_string($rss);
echo ”
“;
Для приложения будем использовать Nginx, Varnish будет направлять запросы ему (8090 порт):
server {
listen 8090;
# Если включен gzip, обязательно нужно выключить!
gzip off;
location / {
index index.php;
}
location ~* .(php)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /home/golotyuk/www/localhost/esi/$fastcgi_script_name;
}
}
Давайте настроим кэш по таким правилам:
backend default { .host = “127.0.0.1”; .port = “8090”; }
# Процедура формирования ключа для кэша
sub vcl_hash {
# Стандартные параметры – имя сервера и URL
set req.hash += req.url;
set req.hash += req.http.host;
# Если установлена сессионная кука, сохраняем ее значение в переменную
if( req.http.cookie ~ “PHPSESSID” ) {
set req.http.X-Varnish-Hashed-On =
regsub( req.http.cookie, “^.*?PHPSESSID=([^;]*?);*.*$”, “1” );
}
# Если в строке запроса мы находим “UID”, то необходимо добавить
# значение сессии в параметры кэширования
if( req.url ~ “/app/.*UID” && req.http.X-Varnish-Hashed-On ) {
set req.hash += req.http.X-Varnish-Hashed-On;
}
# Если в строке запроса мы находим “AUTH”, то необходимо добавить
# флаг статуса (logged in) в параметры кэширования
if( req.url ~ “/app/.*AUTH” && req.http.X-Varnish-Hashed-On ) {
set req.hash += “logged in”;
}
hash;
}
sub vcl_recv {
# Если тип запрос не POST, то ищем объект в кэше
if ( req.request != “POST” )
{
lookup;
}
}
sub vcl_fetch {
# Для запроса “/” используем обработку esi и кэшируем на 1 сутки
if (req.url == “/”) {
esi;
set obj.ttl = 24h;
}
# Для запросов “/app” (ESI вызовы) кэшируем результат на 1 час
elseif (req.url ~ “^/app/”) {
set obj.ttl = 1h;
}
deliver;
}
После проверки скорости получим такие результаты:
ab -n 100 -c 5 http://127.0.0.1/
Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 2 5 3.8 3 18 Waiting: 2 5 3.8 3 18 Total: 2 5 3.8 4 19 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 5 80% 8 90% 12 95% 15 98% 17 99% 19 100% 19 (longest request)
На аналогичном скрипте без ESI, который содержит всю туже логику внутри и каждый раз вызывает PHP:
ab -n 100 -c 5 http://127.0.0.1:8090/index_standard.php
Результаты:
Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 354 579 666.2 458 5484 Waiting: 354 579 666.2 458 5483 Total: 354 579 666.2 458 5484 Percentage of the requests served within a certain time (ms) 50% 458 66% 492 75% 517 80% 539 90% 602 95% 667 98% 3572 99% 5484 100% 5484 (longest request)
Как видим скорость работы отличается в 100 раз!
ESI позволяет использовать кэширование на динамических сайтах с высокой персонализацией. Обратите внимание на альтернативу – SSI в связке с Nginx.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…