Перед придбанням додаткових серверів корисно виміряти, куди витрачаються ресурси наявної системи. У січні 2011 року я описав досвід оптимізації вебпроєктів «Корпорація 2»: кешування CMS, розподіл запитів між Nginx і Apache, роботу PostgreSQL через PgBouncer та кешування PHP-коду.
Цей матеріал зберігає історичний досвід і конфігурації. Команди для PHP 5, XCache, eAccelerator та APC наведено для розуміння старих систем; під час нового розгортання потрібні підтримувані компоненти й налаштування відповідної версії.
1. Кешування CMS і статичні сторінки
У власних давніх дослідах я спостерігав дуже велику різницю між видачею статичного файла та повною генерацією сторінки CMS; у початковій нотатці зазначено діапазон 1 000–10 000 разів. Без опису стенда, запитів і методики це не можна сприймати як універсальний коефіцієнт.
Практичним результатом стала переробка кешування «Корпорація 2»: із динамічного вмісту формували статичні сторінки. Це зменшило повторні обчислення та навантаження на сервер. Для змінних або персоналізованих даних потрібно окремо визначати, коли кеш оновлюється і кому можна показувати збережений результат.
2. Nginx перед Apache
У тодішньому середовищі використовували два рівні вебсервера. Nginx мав самостійно віддавати статичні ресурси й передавати Apache лише ті запити, які потребували його обробки. Мета — уникнути зайвої роботи другого рівня.
Сьогодні конкретний шлях запиту може бути іншим, наприклад із PHP-FPM. Вибір архітектури визначається застосунком. Для проксі-кешування Nginx має окремі директиви proxy_cache; їх не слід плутати з простим передаванням запитів або видачею статичних файлів.
3. PostgreSQL і PgBouncer
У 2011 році в нотатці зазначено понад 500 користувачів онлайн у нашому середовищі. Це опис конкретної експлуатації, а не гарантія такої самої пропускної здатності для іншої системи: кількість відвідувачів не дорівнює кількості одночасно активних запитів.
PgBouncer керує пулом з'єднань PostgreSQL. Режими session, transaction і statement pooling мають різні правила; транзакційний режим обмежує частину можливостей, пов'язаних із сесією. Перед зміною режиму перевіряйте сумісність застосунку.
4. Історичне налаштування XCache
Тоді після порівняння варіантів я обрав XCache. У матеріалі з hilik.org.ua наведено встановлення з портів FreeBSD:
cd /usr/ports/www/xcache/
make install clean
cp /usr/local/share/examples/xcache/xcache.ini /usr/local/etc/php/Збережений приклад xcache.ini:
[xcache-common]
extension = xcache.so
#Включим админ интерфейс
[xcache.admin]
xcache.admin.enable_auth = On
xcache.admin.user = "admin"
#В качестве пароля укажем md5 хеш, создать его можно с
#помощью команды md5 -s "ваш пароль"
xcache.admin.pass = "XXXXXX"
[xcache]
xcache.shm_scheme = "mmap"
#Выделим для кеша 128 мегабайт
xcache.size = 128M
xcache.count = 1
xcache.slots = 8K
xcache.ttl = 0
xcache.gc_interval = 0
xcache.var_size = 0M
xcache.var_count = 1
xcache.var_slots = 8K
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
xcache.readonly_protection = Off
xcache.mmap_path = "/dev/zero"
xcache.coredump_directory = ""
xcache.cacher = On
xcache.stat = On
xcache.optimizer = On
[xcache.coverager]
xcache.coverager = On
xcache.coveragedump_directory = ""У прикладі для кешу виділено 128 МБ. Значення XXXXXX — заповнювач, не готовий пароль. Стара нотатка пропонувала створювати MD5-хеш командою md5 -s "ваш пароль". Це частина історичного механізму XCache, а не рекомендація щодо сучасного зберігання паролів.
Тоді адміністративні файли копіювали з /usr/local/share/examples/xcache/admin до кореня сайту, щоб переглядати статистику. Службовий інтерфейс потребує обмеженого доступу; розміщення у відкритому вебкаталозі саме собою його не захищає.
У початковому переказі були дві неточності: кеш опкодів зберігає скомпільоване представлення PHP-коду, а не обов'язково результат кожного запиту; code coverage dumper стосується покриття виконання коду, а не запобігання переповненню пам'яті. Порівняння швидкодії XCache з іншими кешами без методики тесту також не є загальною гарантією.
5. Історичне встановлення eAccelerator
Наступний фрагмент стосувався PHP 5 та eAccelerator 0.9.6.1:
$ sudo apt-get install php5-dev build-essential
Далее получаем исходные тексты eAccelerator:
$ cd /tmp/
$ wget http://bart.eaccelerator.net/source/0.9.6.1/
eaccelerator-0.9.6.1.tar.bz2
$ tar xvjf eaccelerator-0.9.6.1.tar.bz2
$ cd eaccelerator-0.9.6.1
$ phpize
$ ./configure --enable-eaccelerator=shared
$ make
$ sudo make installУ збереженій команді wget адреса архіву розірвана переносом рядка. Її не слід виконувати як готову послідовність. Це давнє джерело HTTP-завантаження, а не перевірений спосіб установлення сучасного розширення.
Старі команди підготовки каталогу:
$ sudo mkdir -p /var/cache/eaccelerator
$ sudo chmod 0777 /var/cache/eacceleratorРежим 0777 дає запис усім локальним користувачам. Цей рядок збережено для точності архіву; для робочої системи слід призначити потрібного власника та мінімальні права відповідно до способу запуску процесів.
Початкова конфігурація:
# vi /etc/php5/apache2/php.ini
[PHP]
; Подключаем расширение
extension = "eaccelerator.so"
eaccelerator.enable = "1"
; Максимальный размер дискового кэша (Мб)
eaccelerator.shm_size = "64"
; Каталог для хранения кэша
eaccelerator.cache_dir = "/var/cache/eaccelerator"
; Включаем оптимизатор кода
eaccelerator.optimizer = "1"
; Перекомпилировать модифицированные скрипты
eaccelerator.check_mtime = "1"
; Отключаем режим отладки
eaccelerator.debug = "0"
; Кэшировать все файлы (пустой фильтр)
eaccelerator.filter = ""
; Неограниченный размер кэша в памяти
eaccelerator.shm_max = "0"
; В случае отсутствия места в кэше удалять объекты старше
1 часа (3600 секунд)
eaccelerator.shm_ttl = "3600"
eaccelerator.shm_prune_period = "0"
; Кэшировать данные и в памяти, и на диске
eaccelerator.shm_only = "0"
; Сжимать кэшированные данные с максимальным уровнем компрессии
eaccelerator.compress = "1"
eaccelerator.compress_level = "9"Перенос усередині коментаря про 3600 секунд у старому фрагменті також потребує виправлення перед будь-яким використанням. Твердження про прискорення «у десятки разів» було оцінкою з тодішнього матеріалу; методику такого результату не наведено.
6. APC у матеріалах того часу
Огляд із phpcoder.ws/2009-02/apc-setup.html описував установлення через пакет Debian/Ubuntu або PECL:
sudo aptitude install php-apc
sudo pecl install apc
extension=apc.soПісля підключення розширення пропонували перезапустити Apache й переглянути статистику через apc.php. Для Debian наводили каталог /etc/php5/apache2/conf.d/. Діагностичні сторінки не слід залишати загальнодоступними.
У тому огляді повідомляли про приріст швидкості генерації сторінок на 40% для Joomla 1.5.9: 1 000 звернень до головної сторінки у п'яти потоках за допомогою ab2. Це результат конкретного старого тесту, який тут не відтворювався.
Зазначені там обмеження щодо FastCGI, mod_php, CLI та версій PHP відображають старий переказ і не утворюють точного універсального опису всіх випусків APC. Сторінка пакета APC нині повідомляє, що він не підтримується та замінений APCu.
Що перевіряти у сучасному середовищі
Для кешування байткоду PHP використовується OPcache: він зберігає попередньо скомпільований код у спільній пам'яті й зменшує потребу повторного розбору скриптів. Це окремий рівень від кешу даних і готових HTTP-відповідей.
Починайте з вимірювання часу відповіді, навантаження процесора, пам'яті, запитів до бази та частки влучань у кеш. Змінюйте налаштування поступово й порівнюйте результат на однаковому навантаженні. Так можна визначити реальне вузьке місце та обґрунтовано вирішити, чи потрібне потужніше обладнання.