silent 03.10.2010 23:45

Я рекомендуюСверхбыстрый FastCGI для PHP с phpDaemon

Вступление
Как многие уже знают, с версией 5.3 в официальную версию PHP пришел еще один SAPI - fpm и чтобы его завести больше не нужно патчить и компилировать его вручную. Все очень рады, массово отказываются от apache и переходят на nginx и т.п.
ОднакоОднако приложение, как и раньше, образно говоря, работает все по той же схеме:
Инициализация (парсинг php-файлов, инклюдов)Инициализация фреймворка (если и не фреймворк, то все равно что-то делается в любом скрипте перед началом работы)Подключение к серверу базы данных, авторизация и выбор базы данныхВыполнение какой-то работыГенерирование ответаЗакрытие соединения с базой данныхОсвобождение памяти, выделенной под выполнение скрипта
Да, некоторые пункты можно вычеркнуть (частично) в связи с использованием опкод-кешеров (apc, xcache, eaccelerator и т.п.), но хотелось бы большего, правда ведь?
Здрасте, я ваша тетя
Обработку запросов на самом деле можно свести только к пунктам 4 и 5 (к выполнению реальной работы). Именно это нам и предлагает FastCGI-сервер в phpDaemon, о котором на этом сайте я ничего не нашел, как ни странно.

Для затравки - небольшой бенчмарк, там с переходом на FastCGI от phpDaemon приложение без особых переделок получило ускорение в два раза.
Как это работает?
Не будем углубляться в дебри, опишу опять же образно.
При создании инстанса приложения в воркере производится вся инициализация, в приложении выполняется метод, в котором можно подключиться к базе данных и выполнить что-то для подготовки приложения. Дальше воркер просто получает запросы и передает в уже инициализированный инстанс (количество таких запросов перед пересозданием воркера можно задать в настройках).

Все очень просто, не так ли?
Всегда есть какое-то но
И это но - невозможность использования phpDaemon на шаред-хостинге (по крайней мере пока хостеры не захотят). Для установки phpDaemon нужен нормальный доступ к командной строке сервера и нужны такие дополнения как pecl-libevent, pecl-runkit (причем не официальный) и pecl-proctitle (это опционально).

Однако мы с вами сознательные разработчики и очень любим свой проект, поэтому он запущен хотя бы на VPS, поэтому нам это "но" не страшно.
Установка
Проще всего на данный момент в установке пользователям Gentoo Linux, вся установка сводится к добавлению в layman специального оверлея (как - описано на странице по ссылке внизу) и выполнению команды (на самом деле придется еще размаскировать некоторые пакеты для пользователей на стабильной ветке):
1
emerge phpdaemon



Установка на Debian-подобных дистрибутивах выглядит примерно так:
Ставим SAPI cli и dev-пакет, с которым идет phpize, он понадобится для сборки
1
aptitude install php5-cli php5-dev


Ставим libevent
1
aptitude install libevent-dev


Ставим pecl-libevent
1
pecl install libevent


Скорее всего будет предупреждение о том, что это бета-версия и предложение установить через канал, тогда надо будет установить через него.
Ставим pecl-proctitle (дополнение нужно для обзывания процессов говорящими названиями, поэтому оно не обязательно)
1
pecl install proctitle


Ставим runkit (можно и без него, но потеряются некоторые фичи)
1
2
3
4
5
6
git clone git://github.com/zenovich/runkit.git
cd runkit
phpize
./configure --enable-runkit --enable-modify
make
make install


Не забываем прописывать в конфиг загрузку каждого из этих расширений (лучше разбить на несколько файлов, я приведу все вместе):
1
2
3
4
5
vim /etc/php5/conf.d/phpdaemon.ini
extension=libevent.so
extension=proctitle.so
extension=runkit.so
runkit.internal_override=1


Забираем свежую версию phpDaemon куда-нибудь в /opt, к примеру, и создаем ссылку:
1
2
3
cd /opt
git clone git://github.com/kakserpom/phpdaemon.git
ln /usr/bin/phpd /opt/phpdaemon/bin/phpdaemon



Не так страшно, как казалось сначала, правда ведь?

После этого нам надо посмотреть в папке conf файл с примером настройки phpd.conf.example. Убираем постфикс .example и после запуска демона у нас уже будет запущен FastCGI-сервер на 127.0.0.1:9000.
Поставили, а дальше-то что?
А дальше необходимо создать инстанс приложения в папке applications (можно просто поставить туда ссылку) следующего вида:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

class YourApplication extends AppInstance {

public function init() {
// здесь у нас происходит инициализация приложения
}

public function beginRequest($req,$upstream) {
return new YourApplicationRequest($this, $upstream, $req);
}

}

class YourApplicationRequest extends HTTPRequest {

public function run() {
// тут мы обрабатываем наш запрос, все как обычно
echo 'blablabla';
}

}



Для того, чтобы приложение обрабатывало запросы необходимо передавать в phpDaemon параметр APPNAME, в nginx это делается так:

1
fastcgi_param APPNAME YourApplication;


Developers, developers, developers
На мой взгляд от интереса к проекту к его реальному использованию люди доходят довольно редко. Для такого проекта это, на мой взгляд, странновато.
Над проектом постоянно ведутся работы, в нем очень много функций и помимо сервера FastCGI, разработчик отзывчив и всегда идет на встречу. Пробуйте, читайте русскоязычную Wiki, спрашивайте (можно здесь), внедряйте и радуйтесь.

Можно (и даже нужно) даже форкать и пушить свои реквесты.

P.S. Нужно чем-то дополнить пост? Не хватает примеров? Пишите, все сделаем.


Тэги: fastcgi php phpdaemon
+ 9 -
Похожие Поделиться

thebeetlebum 03.10.2010 23:49 #
cat!!!!
konkere 03.10.2010 23:54 #
кошка?!
elbahek 04.10.2010 00:01 #
мне кажется, наш уважаемый коллега имел в виду конкатенацию ;)
exelens 04.10.2010 00:59 #
наш уважаемый коллега

ажамбех пашамбе эшельбе шайтанама
он имел ввиду спрятать, скрыть часть текста со страницы и ленты RSS используя тег КАТ
silent 05.10.2010 19:13 #
конкатенация - это сложение ;)
silent 04.10.2010 00:07 #
совсем забыл, прошу прощения. поправил.
wiz 04.10.2010 08:41 #
cut
ukko 04.10.2010 01:29 #
Анонс очень интригует, но могли бы вы побольше раскрыть о том как работает этот PhpDaemon?

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

И ещё, я так понимаю что инстанс висит постоянно, а как разруливаются права с различными пользователями? Надо где-то вычищать все пользовательские данные из памяти или предусмотрен механизм автоочистки или вообще нет никаких общих данных?

Вообщем хотелось бы больше примеров и объяснения схемы работы.
silent 04.10.2010 05:43 #
phpdaemon - это просто демон, который может спаунить воркеров и выполнять определенные действия с помощью приложений. Приложений в нем довольно много, FastCGI и WebSocketOverComet - одни из них.
На примере приложения FastCGI (вкратце) - приложение при запуске биндит сокет и обрабатывает запросы, приходящие снаружи, и отдает в приложение (какому приложению отдать запрос режает определенный объект), в приложении вызывается beginRequest, которое возвращает HTTPRequest, результат работы которого отдается клиенту.

Если нужно подробнее, то жду вопросов конкретнее :)

Пора перестать приглядываться и уже попробовать на деле, не пожалеете.
silent 04.10.2010 05:44 #
И про пользователей и их права я немного не понял, если честно. Если возможно, уточните.
wiz 04.10.2010 08:42 #
Бугого. На 16м году жизни, авторы поняли, что cgi-модель таки говно...
grandse 04.10.2010 17:52 #
Дело в том, что тогда приходится сервер перегружать, чтобы увидеть изменения на своей странице, или выдумывать что-то более хитрое, как-то замена кода в процессе выполнения (как это сделано по-моему в Erlang, или как это сделано с методами в java).
grandse 04.10.2010 17:59 #
Ну и еще php до версии 5.3 так и не научился очищать нормально память, как написали сами разработчики демона.
silent 04.10.2010 19:52 #
что-то я совсем потерял нить разговора О.о
grandse 05.10.2010 17:31 #
Смотрите:
php в веб работат по принципу:
1. Получили запрос.
2. Компилируем исходный текст, подгружем либы и т.п.
3. Выполняем получивший байткод.
4. Отправляем ответ.
5. Чистим память.
6. Выгружаем байткод.
Всякие кешеры убирают пункты 2 и 6, потому получается значительно быстрее. Но поскольку файл каждый раз не компилируется и не перегружается, то внесение изменений файл влечет за собой необходимость рестарта сервера, чтобы кешер перегрузил данные. Как и делали все perl и java-разработчики. Но разработчики php решили, что это излишество (ну и пусть повышает в несколько раз производительность, кому это нужно то? :) )
Но есть языки, которые поддерживают горячую замену кода (http://en.wikipedia.org/wiki/Hot_swapping#Software). Например, Erlang,java. Для Python есть подобная возможность хоть и боком
silent 05.10.2010 17:56 #
Ну как минимум apc уже давно сам перекомпилирует файл, сразу как только он изменился. Я думаю, другие кешеры тоже неглупые, так что рестарт не нужен в этом случае.

В phpdaemon все по-другому и файлы действительно компилируются один раз - при запуске воркера. Именно поэтому там есть автоимпорт изменений с помощью runkit, так что его тоже рестартовать не надо :)
wiz 04.10.2010 20:25 #
ну да, конечно лучше перезагружать весь код на каждый запрос, ога.
silent 05.10.2010 19:05 #
да не надо никого перезагружать, зачем?
wiz 05.10.2010 19:10 #
это я продолжая тему "калассического пхп"
nikebl 06.10.2010 20:35 #
По мне так еще один вариант кручения FastCGI.
Для обычных веб приложений (типа водпресс) всяко php-fpm лучше будет.
silent 06.10.2010 21:10 #
fpm будет медленнее, особенно на вордпрессе. угадайте почему (или перечитайте статью).
nikebl 12.10.2010 18:55 #
Намного ли? стабильнее ли? вот в чем вопрос... :)

Вроде fpm сам через libevent работает, а с тем же eaccelerator мне кажется немного устапит.
Надо будет погонять на тестовом сервачке под нагрузкой.

Один вопросик:
Вот тут
// тут мы обрабатываем наш запрос, все как обычно
echo 'blablabla';


Ничего не надо добавлять что бы запустить тот же вордпресс? Просто передать переменную через нджинкс?
silent 12.10.2010 19:20 #
Начнем снизу: для каждого приложения необходимо создавать инстанс (кратко описан в конце статьи), просто так взять и запустить WordPress не получится, с ним придется поковыряться.

Теперь остальное
С любым акселератором код приложения все равно будет загружаться и выгружаться из памяти на каждом запросе, с phpdaemon этого нет. Но это - не главная фича. Главная фича - один инстанс обрабатывает множество запросов, т.е. помимо единой компиляции исходников на запуске воркера можно выполнить много чего полезного - соединиться с базой (представляете, вместо сотни-двух коннектов к базе будет штук 20), что-то там предварительно обработать, использовать кеш не через apc/memcache/что-то еще, а хранить что-то мелкое, что нужно всегда прямо в инстансе приложения.

Посмотрите сколько всего делается при выполнении запроса в обычном WordPress'е и большинство этих задач можно выполнять один раз, перед запуском воркера.
А потом посмотрите на то, как загружаются переводы - их можно кешировать в пределах инстанса.
Я думаю, много чего можно придумать в пределах WordPress'а, я просто не очень его хорошо знаю - он меня пугает своим кодом ;)

nikebl 13.10.2010 13:11 #
Спасибо за уточнение, я так и понял изначально.
Это конечно все очень круто, но если задуматься о применении подобных вещей на начальной стадии проектирования хайлоад проекта, то на ум сразу приходят такие вещи как twisted(python), руби с его примочками и т.д.
Переводить существующие проекты на это дело просто не выгодно (дешевле докупить серверных мощностей), только если задумали координальную смену архитектуры.
silent 13.10.2010 14:56 #
Ну, тут все зависит от приложения и от программистов. Относительно грамотно написанные приложения (WordPress к ним не относится, по крайней мере пока) перевести на phpdaemon не очень сложно.
Ну и в любом случае при создании нового проекта с php-программистами дешевле остаться на php :)