Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Воюем за ресурсы:
повышение производительности ZF
         приложения с
помощью phpDaemon + Varnish + ESI
Алексей Качаев
Senior/Lead PHP Developer at
Cogniance

4+ года опыта c PHP

3+ года использования Zend
Framework

Активный участник
zendframework.ru/forum

ZF2 contributor
Мои контакты
Email:
kachayev@gmail.com

Twitter:
@kachayev

Facebook:
http://www.facebook.com/kachayev

Github:
https://github.com/kachayev
О чем мы будем говорить

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

2. как эти пробемы можно решить быстро и практически
безболезнено (как в новом, так и в функционирующем
проекте)

3. контректный zf app и все шаги имплементации того, что
описано в п. 2




  Понимание проблем и путей их решения важно
СХЕМЫ БОЕВЫХ
  ДЕЙСТВИЙ
Проблема 1. Запросы и
инициализация
        Пользователь -> Запрос к серверу

                         =

     nginx + apache2 + php + Zend + application
apache2 + mod_php + Zend
Проблема 1. Запросы и
инициализация
   AJAX + Пользователь => Много запросов к серверу

                             =

    (nginx + apache2 + php + Zend + application) * много



Примеры: autosuggest-поле, валидация формы, загрузка
виджетов и т.д.
apache2 + mod_php + Zend + AJAX
Проблема 1. Запросы и
инициализация
            Rich application = AJAX * много

                           =

 (nginx + apache2 + php + Zend + application) * много (в
                      квадрате)
Куда уходит время

- создание объекта приложения
- чтение и сборка конфигурации (тут даже кеш не спасает)
- загрузка и инициализация ресурсов

Затраты: до 40-60% времени выполнения.
Как хотелось бы? (псевдо код)

Framework::initialize();

while($request = Somewhere::request()) {
  // Тут мы что-то делаем
  // Отдаем ответ
}

Framework::shutdown();
Особенности PHP реализации

1. Проблемы:

  - корявая реализация поддержки Fast-CGI на PHP

2. Существующие решения:

  - php-fpm (FastCGI Process Manager, http://php-fpm.org/)

  - phpDaemon
phpDaemon в студии

Основные возможности

- WebSocket, HTTP, FastCGI, flash
- асинхронные клиенты для MySQL, Memcache, MongoDB и
других
- динамическая перегрузка кода в демон при изменении
файлов
- статистика по количеству запросам, памяти и т.д.
- гибкая настройка worker'ов
...
- многое другое
Схема того, как будет работать с
phpDaemon
Проблема 2. Кеширование HTML

1. Это заманчиво!

- обслуживание большого количества подключений
одновременно
- возможность не инициализировать приложение вообще

2. Это проблематично!

- "размазывание кеша" (для авторизированных
пользователей, по cookies и т.д.)
- точечная инвалидация = "микро-инфаркт" (например,
блок последних комментариев на хабре)
"Размазывание кеша"
"Микро-кеш-инфаркт"
Проблема 2. Возьмем хитростью

1. Varnish, как промежуточный кеширующий сервер
(caching HTTP reverse proxy)
http://www.varnish-cache.org/

2. ESI, как markup language связи логических кусков HTML
http://en.wikipedia.org/wiki/Edge_Side_Includes

<esi:include src="..." onerror="continue"/>

3. Nginx, как front web server
http://nginx.org/
Проблема 2. Расплата за хитрость


ESI = Увеличение количества запросов к backend

Большинство из этих запросов однотипно и нетребует
мощностей всего приложения



            ВЕРНУЛИСЬ К ПРОБЛЕМЕ 1

                         Слава богу, мы уже знаем как ее
                                                решать.
ОБЩАЯ СХЕМА РАБОТЫ С
   КЕШ-СЕРВЕРОМ И
     ДЕМОНАМИ
Общая схема



                Прокси
  Статика
               на daemon
                           Запросы на backend-ы

            Кеширование
ОПИСАНИЕ DEMO
 APPLICATION
Демо приложение: "Конференция"

1. Список докладов из базы данных

2. Добавление докладов в избранное без регистрации

3. Форма поиска по докладам с "подсказыванием" тегов

4. ~ Вход/выход для зарегистрированных пользователей


Sources
https://github.com/kachayev/zfconf-speech
Демо приложение: "Конференция"
Демо приложение: "Конференция"
ВНЕДРЕНИЕ
PHPDAEMON
phpDaemon: установка

1. Официальная документация

https://github.com/kakserpom/phpdaemon/wiki/Installation-
(common)

2. Используется PECL расширения libevent, proctitle
(возможно потребуется пересборка PHP из исходников)

http://tokarchuk.ru/2010/09/%D1%83%D1%81%D1%82%D0%
B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-
phpdaemon-libevent-%D0%BD%D0%B0-ubuntu/


         РУКОВОДСТВА БЫСТРО УСТАРЕВАЮТ
phpDaemon: установка на Ubuntu
0. Нам понадобиться: php-dev, build-essential, git

1. Удаляем старую libevent1

2. Скачиваем новую из ветки 1.4 (2я пока в альфе). Далее
наше любимое .configure && make && make install

3. Устанавливаем pecl extension libevent-0.0.4, добавляем
его подгрузку в /etc/php5/cli/php.ini

4. Аналочиные действия с proctitle

5. Устанавливаем phpDaemon... ->
phpDaemon: установка на Ubuntu
cd /usr/local/lib
git clone git://github.com/kakserpom/phpdaemon.git $path

cd ./phpdaemon
chmod +x ./bin/phpdaemon

ln /usr/bin/phpdaemon /usr/local/lib/phpdaemon/bin/phpdaemon

cp init-scripts/phpd /etc/init.d/
mkdir /etc/phpd/ && cp conf/phpd.conf.example /etc/phpd/phpd.conf

/usr/local/lib/phpdaemon/bin/phpdaemon start




В файл конфигурации добавляем следующее:
HTTP {
enable 1;
    listen 127.0.0.1;
  listen-port 8020;
responder "Example"
}
phpDaemon:
default application
1. Принимает HTTP
запросы на порт, без     р
веб-сервера

2. Siege показал 370
обработанных реквестов
в секунду при 100
одновременных
подключениях.
Прикручиваем к своему проекту
1. Выделяем консистентные блоки (autocomplete,
autosuggest, рендеринг отдельных блоков, виджеты и т.д.)

Важно! Операция на демоне должна затрагивать минимум
различных частей приложения. Подходят: ajax-проверка
полей формы, inline-редактирование данных,
autosuggest/complete и т.д.

2. Отделяем выполнение (Ajax, SSI, ESI etc).

3. Поднимаем демон, реализованный как HTTP App (при
желании можно и Fast CGI).
(следующий слайд)
Прикручиваем к своему проекту
(прд.)
Начинаем с Nginx-подобного конфиг-файла.

/etc/phpd/phpd.conf




                              Примечание:

      (Можно через AppResolver.php, но для
              простых случаев это overkill)
phpDaemon + Zend Framework

Responder application - класс, наследник AppInstance
Должен реализовать следующие функции:

init() - инициализация фреймворка (создаем Zend
Application, бутстрапимся, получаем Front Controller)

beginRequest() - вызывается, когда приложение получает
новый Request для обработки (возвращаем специальный
объект - наследник HTTPRequest)

onReady() - вызывается после отработки инициализации
onShutdown() - завершаем работу фрейморка
phpDaemon + ZF (окружение)

/usr/local/phpdaemon/applications/ZfconfApp.php
phpDaemon + ZF (app instance)
phpDaemon -> Request

HTTPRequest содержит все нужные нам данные GET,
POST, COOKIES, SESSION и т.д.

В наследнике должны реализовать функции

run() - передать в приложение новые суперглобальные,
подготовить Response, должны вернуть Request::DONE
(сбрасываем Request, Response объекты Front Controller'а и
выполняем run())

onFinish() - возвращаем подготовленный ранее Response
phpDaemon -> Request
Nginx -> phpDaemon

4. Nginx "ловит" адрес и перенаправляет его на backend
(HTTP, или FastCGI)

Полный разбор nginx кофигурации не делаем.
Только момент "перехвата" URL.
Несколько замечаний (номер 1)

Важно! При реализации данного подхода критически
важно, чтобы инициализация (Bootstrap, Application
Resources) не делала ничего request-зависимого.

Например.

Присваивание текущего языка (current language) в Bootstrap
- это очень большая ошибка. Для этого есть плагины.

(вспоминаем цикл диспечирезации).
Несколько замечаний (номер 2)

Важно! Внимательно следите, чтобы никто "не посмел"
отправить клиенту хоть какие-то данные, до тех пор, пока
это явно не сделает phpDaemon.

Например.

В коде Action'а:
$this->_helper->json($data);

Приведет к:
(примеров много)
Что получилось?

Autosuggest отдается демоном.
Known issues

1. Debian, Ubuntu - проблемы с рестартом при "зависших"
подключениях (аналогично Mongo). "Спасает":




2. Если работа ведется без веб-сервера, то нужно помнить
о статике. Например, попытка обработать запрос
/favicon.ico с помощью Zend отправляет phpDaemon в
глубокий down.

Т.е. без веб-сервера фильтруем статику в ручную.
Что дальше?

Неблокирующий MySQL драйвер
Неблокирующий Memcache клиент
И т.д.

Как это работает? (на примере MySQL)

1. Запрос (обработчик) делает request на MySQL и вешает
callback

2. Вызывается $this->sleep(30) - диспечер выбрасывает
процесс из обработки, чтобы вернуться через 30 сек

3. В callback делается $this->wakeup()
Что дальше?

В последних версиях появилась возможность использовать

Sandbox

Fatal error воркера не приводит к перезапуску демона.
Оценим полученный результат

+ Плюсы

1. Снижение нагрузки на сервер и потребляемых ресурсов
2. Уменьшение времени ожидания ответа

- Минусы

1. Усложнение деплоя
2. Усложнение тестирования
3. Усложнение управления приложением
Полезные материалы по теме

0. "Офф. сайт"
http://phpdaemon.net/

1. phpDaemon - фреймворк асинхронных приложений
http://habrahabr.ru/blogs/php/79377/

2. Wiki документация
https://github.com/kakserpom/phpdaemon/wiki
ВНЕДРЕНИЕ
 VARNISH
Varnish: сильные стороны

1. Мощный язык конфигурации VCL (Varnish Configuration
Language)

2. Легкость горизонтального масштабирования

3. Возможность использования механизмов балансировки
нагрзуки с учетом времени ответов и загруженности бекенд
серверов

4. Поддержка ESI разметки

5. Большое количество отличных утилит для
профайлирования и мониторинга
Varnish Administration Console
Varhish: установка на Ubuntu
cd /tmp
sudo bash

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
echo "deb http://repo.varnish-cache.org/ubuntu/ $(lsb_release -s -c) varnish-2.1" >> /etc/apt/source.list

apt-get update && apt-get install varnish

# Далее вы можете использовать init-скрипт
* Usage: /etc/init.d/varnish {start|stop|restart|force-reload}




Установка на других платформах:
http://www.varnish-cache.org/docs

Установка web-based admin console:
http://www.varnish-cache.org/trac/wiki/WebGui
Конфигурация демона

/etc/default/varnish для Ubuntu
- необходимость запуска демона START=yes
- порт, который будет слушать демон (:81)
VCL файл

/etc/varnish/varnish.vcl
- описание backend
VCL файл
/etc/varnish/varnish.vcl
- описание процедур hash, fetch, deliver, hit, recv
VCL файл
/etc/varnish/varnish.vcl
- описание процедур hash, fetch, deliver, hit, recv
VCL файл
VCL файл
/etc/varnish/varnish.vcl
- описание процедур hash, fetch, deliver, hit, recv
Nginx location resolving
PhpDaemon workers

В указанном выше примере использовался один и тот же
ZfconfApp на порту 8091.

Но, часто есть смысл разграничивать обработчики:
- отдельный worker на autosuggest
- отдельный worker на рендеринг AJAX-видета

В таких случаях используется AppResolver.php (можно
прописывать правила "раздачи" запросов на worker-ы).
Использование ESI

Основное

- Формат: <esi:include src="" />
- Директивы alt и onerror на данный момент не
поддерживаются
- для Zend-a самописный View Helper (рендер include и
отправление заголовка esi-enabled)
Использование ESI

Обратить внимание

- отключаем сжатие (nginx: gzip off, apache2: no deflate)

- проблемы с ETag, If-Non-Match

- отслеживание поведения кеша по URL (nginx rewrite,
apache2 rewrite, Zend routing, URL-mark etc)

- готовьтесь к сюрпризам :)
А можно ли по другому?

По аналогу со схемой Nginx + Varnish + ESI можно
использовать схему

Nginx + SSI + Memcache

Минусы

- nginx не умеет писать контент в memcache (нужно писать
со стороны backend-a)
- слабые возможности конфигурирования кеш-ключа
- сложно управлять кешированием
Подводные камни

1. Правильность разграничения контента

Например, если HTML различается по языку, хранящемуся в cookies, то
это нужно учитывать.
Подводные камни

2. Очистка выполняется через CLI или отправкой запроса
HTTP PURGE

Не самая простая процедура, поэтому для dev-режима нужно
предусмотреть возможность работы с TTL=0.

Очистка varnish-кеша по объекто-зависимым событиям.
Пример: очистить кеш списка докладов после внесения
изменений пользователем.

- переопределить CacheManager
- обернуть необходимые cache backend в специальные
враппер
Подводные камни




Конкретная реализация зависит от общей схемы работы
с кешем
Подводные камни

3. Управление кешем со стороны клиента (Cache-Control,
etc)
В demo app есть пример работы заголовками клиента



4. Документация во многом не соответствует правде.
Нагрузочное тестирование
результата
Не очень информативно и предсказуемо, но по факту:
ab -n 100 -c 5 http://zfconf.loc/




Преимущество: response time практически не
увеличивается при повышении concurrency level.
Ссылки на полезные материалы

Varnish docs and tutorials:
• http://www.varnish-cache.org/docs/2.1/index.html
• http://www.ibm.com/developerworks/opensource/library/os-php-
  varnish/?ca=dgr-lnxw06Varnish-PHP
• http://www.mediawiki.org/wiki/Manual:Varnish_caching

ESI:
• http://www.varnish-cache.org/trac/wiki/ESIfeatures
• http://cd34.com/blog/infrastructure/no-esi-processing-first-char-not/

VCL:
• http://www.varnish-cache.org/docs/2.1/tutorial/vcl.html
Спасибо за внимание!



            Вопросы
              ???
Мои контакты
Email:
kachayev@gmail.com

Twitter:
@kachayev

Facebook:
http://www.facebook.com/kachayev

Github:
https://github.com/kachayev

More Related Content

Воюем за ресурсы (ZFConf2011)

  • 1. Воюем за ресурсы: повышение производительности ZF приложения с помощью phpDaemon + Varnish + ESI
  • 2. Алексей Качаев Senior/Lead PHP Developer at Cogniance 4+ года опыта c PHP 3+ года использования Zend Framework Активный участник zendframework.ru/forum ZF2 contributor
  • 4. О чем мы будем говорить • о ресурсах и о том, почему их не хватает • о времени и о том, куда оно девается • о пользователях, современных веб-приложениях и о проблемах, с ними связанными • ...
  • 5. Как мы будем говорить 1. 2 проблемы в использовании ресурсов на реальных примерах из широкой практики 2. как эти пробемы можно решить быстро и практически безболезнено (как в новом, так и в функционирующем проекте) 3. контректный zf app и все шаги имплементации того, что описано в п. 2 Понимание проблем и путей их решения важно
  • 6. СХЕМЫ БОЕВЫХ ДЕЙСТВИЙ
  • 7. Проблема 1. Запросы и инициализация Пользователь -> Запрос к серверу = nginx + apache2 + php + Zend + application
  • 9. Проблема 1. Запросы и инициализация AJAX + Пользователь => Много запросов к серверу = (nginx + apache2 + php + Zend + application) * много Примеры: autosuggest-поле, валидация формы, загрузка виджетов и т.д.
  • 10. apache2 + mod_php + Zend + AJAX
  • 11. Проблема 1. Запросы и инициализация Rich application = AJAX * много = (nginx + apache2 + php + Zend + application) * много (в квадрате)
  • 12. Куда уходит время - создание объекта приложения - чтение и сборка конфигурации (тут даже кеш не спасает) - загрузка и инициализация ресурсов Затраты: до 40-60% времени выполнения.
  • 13. Как хотелось бы? (псевдо код) Framework::initialize(); while($request = Somewhere::request()) { // Тут мы что-то делаем // Отдаем ответ } Framework::shutdown();
  • 14. Особенности PHP реализации 1. Проблемы: - корявая реализация поддержки Fast-CGI на PHP 2. Существующие решения: - php-fpm (FastCGI Process Manager, http://php-fpm.org/) - phpDaemon
  • 15. phpDaemon в студии Основные возможности - WebSocket, HTTP, FastCGI, flash - асинхронные клиенты для MySQL, Memcache, MongoDB и других - динамическая перегрузка кода в демон при изменении файлов - статистика по количеству запросам, памяти и т.д. - гибкая настройка worker'ов ... - многое другое
  • 16. Схема того, как будет работать с phpDaemon
  • 17. Проблема 2. Кеширование HTML 1. Это заманчиво! - обслуживание большого количества подключений одновременно - возможность не инициализировать приложение вообще 2. Это проблематично! - "размазывание кеша" (для авторизированных пользователей, по cookies и т.д.) - точечная инвалидация = "микро-инфаркт" (например, блок последних комментариев на хабре)
  • 20. Проблема 2. Возьмем хитростью 1. Varnish, как промежуточный кеширующий сервер (caching HTTP reverse proxy) http://www.varnish-cache.org/ 2. ESI, как markup language связи логических кусков HTML http://en.wikipedia.org/wiki/Edge_Side_Includes <esi:include src="..." onerror="continue"/> 3. Nginx, как front web server http://nginx.org/
  • 21. Проблема 2. Расплата за хитрость ESI = Увеличение количества запросов к backend Большинство из этих запросов однотипно и нетребует мощностей всего приложения ВЕРНУЛИСЬ К ПРОБЛЕМЕ 1 Слава богу, мы уже знаем как ее решать.
  • 22. ОБЩАЯ СХЕМА РАБОТЫ С КЕШ-СЕРВЕРОМ И ДЕМОНАМИ
  • 23. Общая схема Прокси Статика на daemon Запросы на backend-ы Кеширование
  • 25. Демо приложение: "Конференция" 1. Список докладов из базы данных 2. Добавление докладов в избранное без регистрации 3. Форма поиска по докладам с "подсказыванием" тегов 4. ~ Вход/выход для зарегистрированных пользователей Sources https://github.com/kachayev/zfconf-speech
  • 29. phpDaemon: установка 1. Официальная документация https://github.com/kakserpom/phpdaemon/wiki/Installation- (common) 2. Используется PECL расширения libevent, proctitle (возможно потребуется пересборка PHP из исходников) http://tokarchuk.ru/2010/09/%D1%83%D1%81%D1%82%D0% B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0- phpdaemon-libevent-%D0%BD%D0%B0-ubuntu/ РУКОВОДСТВА БЫСТРО УСТАРЕВАЮТ
  • 30. phpDaemon: установка на Ubuntu 0. Нам понадобиться: php-dev, build-essential, git 1. Удаляем старую libevent1 2. Скачиваем новую из ветки 1.4 (2я пока в альфе). Далее наше любимое .configure && make && make install 3. Устанавливаем pecl extension libevent-0.0.4, добавляем его подгрузку в /etc/php5/cli/php.ini 4. Аналочиные действия с proctitle 5. Устанавливаем phpDaemon... ->
  • 31. phpDaemon: установка на Ubuntu cd /usr/local/lib git clone git://github.com/kakserpom/phpdaemon.git $path cd ./phpdaemon chmod +x ./bin/phpdaemon ln /usr/bin/phpdaemon /usr/local/lib/phpdaemon/bin/phpdaemon cp init-scripts/phpd /etc/init.d/ mkdir /etc/phpd/ && cp conf/phpd.conf.example /etc/phpd/phpd.conf /usr/local/lib/phpdaemon/bin/phpdaemon start В файл конфигурации добавляем следующее: HTTP { enable 1; listen 127.0.0.1; listen-port 8020; responder "Example" }
  • 32. phpDaemon: default application 1. Принимает HTTP запросы на порт, без р веб-сервера 2. Siege показал 370 обработанных реквестов в секунду при 100 одновременных подключениях.
  • 33. Прикручиваем к своему проекту 1. Выделяем консистентные блоки (autocomplete, autosuggest, рендеринг отдельных блоков, виджеты и т.д.) Важно! Операция на демоне должна затрагивать минимум различных частей приложения. Подходят: ajax-проверка полей формы, inline-редактирование данных, autosuggest/complete и т.д. 2. Отделяем выполнение (Ajax, SSI, ESI etc). 3. Поднимаем демон, реализованный как HTTP App (при желании можно и Fast CGI). (следующий слайд)
  • 34. Прикручиваем к своему проекту (прд.) Начинаем с Nginx-подобного конфиг-файла. /etc/phpd/phpd.conf Примечание: (Можно через AppResolver.php, но для простых случаев это overkill)
  • 35. phpDaemon + Zend Framework Responder application - класс, наследник AppInstance Должен реализовать следующие функции: init() - инициализация фреймворка (создаем Zend Application, бутстрапимся, получаем Front Controller) beginRequest() - вызывается, когда приложение получает новый Request для обработки (возвращаем специальный объект - наследник HTTPRequest) onReady() - вызывается после отработки инициализации onShutdown() - завершаем работу фрейморка
  • 36. phpDaemon + ZF (окружение) /usr/local/phpdaemon/applications/ZfconfApp.php
  • 37. phpDaemon + ZF (app instance)
  • 38. phpDaemon -> Request HTTPRequest содержит все нужные нам данные GET, POST, COOKIES, SESSION и т.д. В наследнике должны реализовать функции run() - передать в приложение новые суперглобальные, подготовить Response, должны вернуть Request::DONE (сбрасываем Request, Response объекты Front Controller'а и выполняем run()) onFinish() - возвращаем подготовленный ранее Response
  • 40. Nginx -> phpDaemon 4. Nginx "ловит" адрес и перенаправляет его на backend (HTTP, или FastCGI) Полный разбор nginx кофигурации не делаем. Только момент "перехвата" URL.
  • 41. Несколько замечаний (номер 1) Важно! При реализации данного подхода критически важно, чтобы инициализация (Bootstrap, Application Resources) не делала ничего request-зависимого. Например. Присваивание текущего языка (current language) в Bootstrap - это очень большая ошибка. Для этого есть плагины. (вспоминаем цикл диспечирезации).
  • 42. Несколько замечаний (номер 2) Важно! Внимательно следите, чтобы никто "не посмел" отправить клиенту хоть какие-то данные, до тех пор, пока это явно не сделает phpDaemon. Например. В коде Action'а: $this->_helper->json($data); Приведет к: (примеров много)
  • 44. Known issues 1. Debian, Ubuntu - проблемы с рестартом при "зависших" подключениях (аналогично Mongo). "Спасает": 2. Если работа ведется без веб-сервера, то нужно помнить о статике. Например, попытка обработать запрос /favicon.ico с помощью Zend отправляет phpDaemon в глубокий down. Т.е. без веб-сервера фильтруем статику в ручную.
  • 45. Что дальше? Неблокирующий MySQL драйвер Неблокирующий Memcache клиент И т.д. Как это работает? (на примере MySQL) 1. Запрос (обработчик) делает request на MySQL и вешает callback 2. Вызывается $this->sleep(30) - диспечер выбрасывает процесс из обработки, чтобы вернуться через 30 сек 3. В callback делается $this->wakeup()
  • 46. Что дальше? В последних версиях появилась возможность использовать Sandbox Fatal error воркера не приводит к перезапуску демона.
  • 47. Оценим полученный результат + Плюсы 1. Снижение нагрузки на сервер и потребляемых ресурсов 2. Уменьшение времени ожидания ответа - Минусы 1. Усложнение деплоя 2. Усложнение тестирования 3. Усложнение управления приложением
  • 48. Полезные материалы по теме 0. "Офф. сайт" http://phpdaemon.net/ 1. phpDaemon - фреймворк асинхронных приложений http://habrahabr.ru/blogs/php/79377/ 2. Wiki документация https://github.com/kakserpom/phpdaemon/wiki
  • 50. Varnish: сильные стороны 1. Мощный язык конфигурации VCL (Varnish Configuration Language) 2. Легкость горизонтального масштабирования 3. Возможность использования механизмов балансировки нагрзуки с учетом времени ответов и загруженности бекенд серверов 4. Поддержка ESI разметки 5. Большое количество отличных утилит для профайлирования и мониторинга
  • 52. Varhish: установка на Ubuntu cd /tmp sudo bash curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add - echo "deb http://repo.varnish-cache.org/ubuntu/ $(lsb_release -s -c) varnish-2.1" >> /etc/apt/source.list apt-get update && apt-get install varnish # Далее вы можете использовать init-скрипт * Usage: /etc/init.d/varnish {start|stop|restart|force-reload} Установка на других платформах: http://www.varnish-cache.org/docs Установка web-based admin console: http://www.varnish-cache.org/trac/wiki/WebGui
  • 53. Конфигурация демона /etc/default/varnish для Ubuntu - необходимость запуска демона START=yes - порт, который будет слушать демон (:81)
  • 55. VCL файл /etc/varnish/varnish.vcl - описание процедур hash, fetch, deliver, hit, recv
  • 56. VCL файл /etc/varnish/varnish.vcl - описание процедур hash, fetch, deliver, hit, recv
  • 58. VCL файл /etc/varnish/varnish.vcl - описание процедур hash, fetch, deliver, hit, recv
  • 60. PhpDaemon workers В указанном выше примере использовался один и тот же ZfconfApp на порту 8091. Но, часто есть смысл разграничивать обработчики: - отдельный worker на autosuggest - отдельный worker на рендеринг AJAX-видета В таких случаях используется AppResolver.php (можно прописывать правила "раздачи" запросов на worker-ы).
  • 61. Использование ESI Основное - Формат: <esi:include src="" /> - Директивы alt и onerror на данный момент не поддерживаются - для Zend-a самописный View Helper (рендер include и отправление заголовка esi-enabled)
  • 62. Использование ESI Обратить внимание - отключаем сжатие (nginx: gzip off, apache2: no deflate) - проблемы с ETag, If-Non-Match - отслеживание поведения кеша по URL (nginx rewrite, apache2 rewrite, Zend routing, URL-mark etc) - готовьтесь к сюрпризам :)
  • 63. А можно ли по другому? По аналогу со схемой Nginx + Varnish + ESI можно использовать схему Nginx + SSI + Memcache Минусы - nginx не умеет писать контент в memcache (нужно писать со стороны backend-a) - слабые возможности конфигурирования кеш-ключа - сложно управлять кешированием
  • 64. Подводные камни 1. Правильность разграничения контента Например, если HTML различается по языку, хранящемуся в cookies, то это нужно учитывать.
  • 65. Подводные камни 2. Очистка выполняется через CLI или отправкой запроса HTTP PURGE Не самая простая процедура, поэтому для dev-режима нужно предусмотреть возможность работы с TTL=0. Очистка varnish-кеша по объекто-зависимым событиям. Пример: очистить кеш списка докладов после внесения изменений пользователем. - переопределить CacheManager - обернуть необходимые cache backend в специальные враппер
  • 66. Подводные камни Конкретная реализация зависит от общей схемы работы с кешем
  • 67. Подводные камни 3. Управление кешем со стороны клиента (Cache-Control, etc) В demo app есть пример работы заголовками клиента 4. Документация во многом не соответствует правде.
  • 68. Нагрузочное тестирование результата Не очень информативно и предсказуемо, но по факту: ab -n 100 -c 5 http://zfconf.loc/ Преимущество: response time практически не увеличивается при повышении concurrency level.
  • 69. Ссылки на полезные материалы Varnish docs and tutorials: • http://www.varnish-cache.org/docs/2.1/index.html • http://www.ibm.com/developerworks/opensource/library/os-php- varnish/?ca=dgr-lnxw06Varnish-PHP • http://www.mediawiki.org/wiki/Manual:Varnish_caching ESI: • http://www.varnish-cache.org/trac/wiki/ESIfeatures • http://cd34.com/blog/infrastructure/no-esi-processing-first-char-not/ VCL: • http://www.varnish-cache.org/docs/2.1/tutorial/vcl.html