FastNetMon

Показаны сообщения с ярлыком mod_fcgid. Показать все сообщения
Показаны сообщения с ярлыком mod_fcgid. Показать все сообщения

вторник, 2 ноября 2010 г.

mod_fcgid +eAccelerator + SHM

Как бы это глупо ни звучало, но при использовании eAccelerator в режиме PHP FastCGI он создает блок shm памяти для КАЖДОГО рабочего процесса PHP. То есть, если Вы ставитие лимит в 64 мегабайта кэша, то будет выделено дополнительно N*64мб памяти. Жуть не правда ли? Также, очевидно, все скрипты перекомпилируются заново при запуске очередного рабочего процесса, что сводит весь профит на нет.

А вот пруфлинк в баг-трекере eAccelerator: http://eaccelerator.net/ticket/3

На практике же все именно так и есть, имеем 3 рабочих процесса пользователя v001001:
ps aux | grep v001001
v001001 20588 0.2 0.2 336936 69056 ? S 00:33 0:15 /usr/bin/php5-cgi php
root 22492 0.0 0.0 87884 800 pts/2 S+ 02:32 0:00 grep v001001
v001001 24284 0.4 0.2 335060 63152 ? S 00:49 0:30 /usr/bin/php5-cgi php
v001001 24285 0.0 0.2 336712 57952 ? S 00:49 0:05 /usr/bin/php5-cgi php

И смотрим использование SHM памяти:
ipcs -m | grep v001001
0x00000000 266010721 v001001 600 33554432 1 dest
0x00000000 259981492 v001001 600 33554432 1 dest
0x00000000 266043689 v001001 600 33554432 1 dest
0x00000000 1069875720 v001001 600 1048576 0

То есть, 3 по 32 мегабайта. Ну что же, немного... но если у Вас таких процессов сотни 3:

ps aux | grep php5-cgi | wc -l
320

А это ни много ни мало, а целых 9 гигабайт забитых мусором. Что же делать, что же делать? Хранить кэш на диске :)

четверг, 24 июня 2010 г.

Как ограничить число php5-cgi процессов при использовании mod_fcgid?

Есть такая директива:

DefaultMaxClassProcessCount 2

Она ограничит число процессов для одного сайта двумя штуками? Или для пользователя? А хрен вот знает на самом деле.

Тут пишут, что поведение директивы было изменено в версии 2.3.5.
Somehow there was a decision made that changed max PHP processes from
per-user to per-vhost between the old mod-fcgid and the newer 2.3.5 version.

Так что попробуем разобраться с тем, что же значит эта директива для версии mod_fcgid 2.2-1 (Debian 5 Lenny) на основе исходных кодов.

cd /usr/src/
apt-get source libapache2-mod-fcgid
apt-get build-dep -y libapache2-mod-fcgid
cd libapache2-mod-fcgid-2.2

Первое упоминание этой опции идет в файле mod_fcgid.c:
571 AP_INIT_TAKE1("DefaultMaxClassProcessCount",
572 set_max_class_process,
573 NULL, RSRC_CONF,
574 "Max process count of one class of fastcgi application"),

Далее эта функция упоминается в файле fcgid_conf.c:
465 const char *set_max_class_process(cmd_parms * cmd, void *dummy,
466 const char *arg)
467 {
468 server_rec *s = cmd->server;
469 fcgid_server_conf *config =
470 ap_get_module_config(s->module_config, &fcgid_module);
471 config->max_class_process_count = atol(arg);
472 return NULL;
473 }

Чуть нижее нее есть функция получения значения этого лимита:
475 int get_max_class_process(server_rec * s)
476 {
477 fcgid_server_conf *config =
478 ap_get_module_config(s->module_config, &fcgid_module);
479 return config ? config->
480 max_class_process_count : DEFAULT_MAX_CLASS_PROCESS_COUNT;
481 }

Далее вторая функция вызывается в файле fcgid_spawn_ctl.c (предпоследняя строка) для инициализации переменной g_max_class_process :
99 void spawn_control_init(server_rec * main_server, apr_pool_t * configpool)
100 {
101 apr_status_t rv;
102
103 if ((rv = apr_pool_create(&g_stat_pool, configpool)) != APR_SUCCESS) {
104 /* Fatal error */
105 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
106 "mod_fcgid: can't create stat pool");
107 exit(1);
108 }
109
110 /* Initialize the variables from configuration */
111 g_time_score = get_time_score(main_server);
112 g_termination_score = get_termination_score(main_server);
113 g_spawn_score = get_spawn_score(main_server);
114 g_score_uplimit = get_spawnscore_uplimit(main_server);
115 g_max_process = get_max_process(main_server); // этот лимит установлен стандартно в DEFAULT_MAX_PROCESS_COUNT, а он равен 1000
116 g_max_class_process = get_max_class_process(main_server); // этот лимит стандартно установлен в DEFAULT_MAX_CLASS_PROCESS_COUNT, а он равен 100
117 g_min_class_process = get_min_class_process(main_server); // этот лимит стандартно установлен в DEFAULT_MIN_CLASS_PROCESS_COUNT, а он равен 3
118 }


Далее идет использование переменных g_max_class_process и g_max_process (глобальный лимит FastCGI процессов) в коде функции is_spawn_allowed:
182
183 /* Total process count higher than up limit? */
184 if (g_total_process >= g_max_process) {
185 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
186 "mod_fcgid: %s total process count %d >= %d, skip the spawn requ
est",
187 command->cgipath, g_total_process, g_max_process);
188 return 0;
189 }
190
191 /*
192 Process count of this class higher than up limit?
193 */
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process);
200 return 0;
201 }


Где g_max_process (глобальный лимит процессов) сравниваем с g_total_process, тут все очевидно, это глобальное число процессов, которые были форкнуты. А вот g_max_class_process сравнивается с неким current_node->process_counter. Что есть этот current_node ?

Идем далее, функция is_spawn_allowed имеет прототип int is_spawn_allowed(server_rec * main_server, fcgid_command * command), по логике, второй параметр, command - это запускаемый в данный момент бинарик (блок информации о нем), как раз там мы и можем понять, каким образом они разделяются.

Вот описание структуры fcgid_command (см. fcgid_pm.h):
8 typedef struct {
9 char cgipath[_POSIX_PATH_MAX];
10 char wrapperpath[_POSIX_PATH_MAX];
11 apr_ino_t inode; // он-то нам и нужен!
12 dev_t deviceid;
13 apr_size_t share_grp_id;
14 uid_t uid; /* For suEXEC */
15 gid_t gid; /* For suEXEC */
16 int userdir; /* For suEXEC */
17 char initenv_key[INITENV_CNT][INITENV_KEY_LEN];
18 char initenv_val[INITENV_CNT][INITENV_VAL_LEN];
19 } fcgid_command;

Вызов функции is_spawn_allowed идет из функции pm_main (файл fcgid_pm_main.c) в виде:
466 apr_status_t pm_main(server_rec * main_server, apr_pool_t * configpool)
467 {
468 fcgid_command command;
469
470 /* Initialize the variables from configuration */
471 g_idle_timeout = get_idle_timeout(main_server);
472 g_idle_scan_interval = get_idle_scan_interval(main_server);
473 g_busy_scan_interval = get_busy_scan_interval(main_server);
474 g_proc_lifetime = get_proc_lifetime(main_server);
475 g_error_scan_interval = get_error_scan_interval(main_server);
476 g_zombie_scan_interval = get_zombie_scan_interval(main_server);
477 g_busy_timeout = get_busy_timeout(main_server);
478 g_busy_timeout += 10;
479 g_shutdown_timeout = get_shutdown_timeout(main_server);
480
481 while (1) {
482 if (procmgr_must_exit())
483 break;
484
485 /* Wait for command */
486 if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) {
487 if (is_spawn_allowed(main_server, &command))
488 fastcgi_spawn(&command, main_server, configpool);
489
490 procmgr_finish_notify(main_server);
491 }
492


То есть, содержимое command мы получаем откуда-то извне посредством вызова команды procmgr_peek_cmd, которая читает этот самый command из некоего pipe (способ межпроцессного обмена данными) посредством функции (вот ее описание) apr_file_read_full(g_pm_read_pipe, command, sizeof(*command), NULL), файл arch/unix/fcgid_pm_unix.c:

464 apr_status_t procmgr_peek_cmd(fcgid_command * command,
465 server_rec * main_server)
466 {
467 apr_status_t rv;
468
469 /* Sanity check */
470 if (!g_pm_read_pipe)
471 return APR_EPIPE;
472
473 /* Wait for next command */
474 rv = apr_wait_for_io_or_timeout(g_pm_read_pipe, NULL, FOR_READ);
475
476 /* Log any unexpect result */
477 if (rv != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(rv)) {
478 ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
479 "mod_fcgid: wait io error while getting message from pipe");
480 return rv;
481 }
482
483 /* Timeout */
484 if (rv != APR_SUCCESS)
485 return rv;
486
487 return apr_file_read_full(g_pm_read_pipe, command, sizeof(*command),
488 NULL);
489 }

Этот pipe создается следующей функцией (см. arch/unix/fcgid_pm_unix.c):
308 if ((rv = apr_file_pipe_create(&g_pm_read_pipe, &g_ap_write_pipe,

pipe этот предназначен для обмена данными между Апачем и процесс-менеджером (так понимаю, он является отдельным процессом), который отфоркивает нам процессы.

Процесс-менеджер создается функцией apr_proc_fork, это обычный fork процесса (см. arch/unix/fcgid_pm_unix.c):
198 static apr_status_t
199 create_process_manager(server_rec * main_server, apr_pool_t * configpool)
200 {
201 apr_status_t rv;
202
203 g_process_manager =
204 (apr_proc_t *) apr_pcalloc(configpool, sizeof(*g_process_manager));
205 rv = apr_proc_fork(g_process_manager, configpool);


Осталось понять, откуда эти блоки данных типа fcgid_command отправляются.

А делает это функция procmgr_post_spawn_cmd (arch/unix/fcgid_pm_unix.c):
401 apr_status_t procmgr_post_spawn_cmd(fcgid_command * command,
402 request_rec * r)
403 {
404 apr_status_t rv;
405 char notifybyte;
406 apr_size_t nbytes = sizeof(*command);
407 server_rec *main_server = r->server;
408
409 /* Sanity check first */
410 if (g_caughtSigTerm || !g_ap_write_pipe)
411 return APR_SUCCESS;
412
413 /* Get the global mutex before posting the request */
414 if ((rv = apr_global_mutex_lock(g_pipelock)) != APR_SUCCESS) {
415 ap_log_error(APLOG_MARK, LOG_WARNING, rv, main_server,
416 "mod_fcgid: can't get pipe mutex");
417 exit(0);
418 }
419
420 if ((rv =
421 apr_file_write_full(g_ap_write_pipe, command, nbytes,
422 NULL)) != APR_SUCCESS) {


А вызывается она из функции handle_request (fcgid_bridge.c):
270 static int
271 handle_request(request_rec * r, int role, const char *argv0,
272 fcgid_wrapper_conf * wrapper_conf,
273 apr_bucket_brigade * output_brigade)
274 {
...
342
343 /* Send a spawn request if I can't get a process slot */
344 procmgr_post_spawn_cmd(&fcgi_request, r);


В частности посылается структура fcgi_request, которая чуть выше инициализируется вот так:
320 /* Init spawn request */
321 procmgr_init_spawn_cmd(&fcgi_request, r, argv0, deviceid,
322 inode, shareid);
323

Сама функция инициализации command имеет вид:
337 void procmgr_init_spawn_cmd(fcgid_command * command, request_rec * r,
338 const char *argv0, dev_t deviceid,
339 apr_ino_t inode, apr_size_t share_grp_id)
340 {
...
384 strncpy(command->cgipath, argv0, _POSIX_PATH_MAX);
385 command->cgipath[_POSIX_PATH_MAX - 1] = '\0';
386 command->deviceid = deviceid;
387 command->inode = inode; // внимание!
388 command->share_grp_id = share_grp_id;
389
390 /* Update fcgid_command with wrapper info */
391 command->wrapperpath[0] = '\0';
392 if ((wrapperconf = get_wrapper_info(argv0, r))) {
393 strncpy(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX);
394 command->wrapperpath[_POSIX_PATH_MAX - 1] = '\0';
395 command->deviceid = wrapperconf->deviceid;
396 command->inode = wrapperconf->inode; // внимание!
397 command->share_grp_id = wrapperconf->share_group_id;
398 }


Итого, у нас два варианта заполнения поля inode - обычный и из wrapper. И использование / не использование inode от wrapper управляется функцией get_wrapper_info (fcgid_conf.c), которая имеет вид:
846 fcgid_wrapper_conf *get_wrapper_info(const char *cgipath, request_rec * r)
847 {
848 char *extension;
849 fcgid_wrapper_conf *wrapper;
850 fcgid_dir_conf *config =
851 ap_get_module_config(r->per_dir_config, &fcgid_module);
852
853 /* Get file name extension */
854 extension = ap_strrchr_c(cgipath, '.');
855 if (extension == NULL)
856 return NULL;
857
858 /* Search file name extension in per_dir_config */
859 if (config
860 && (wrapper =
861 apr_hash_get(config->wrapper_info_hash, extension,
862 strlen(extension))))
863 return wrapper;
864
865 return NULL;
866 }

В моем случае wrapper используется и задается директивой FCGIWrapper в конфиге Апача, далее (fcgid_conf.c) для инициализации таблицы этих самых wrapper`ов используется функция set_wrapper_config (fcgid_conf.c):
773 const char *set_wrapper_config(cmd_parms * cmd, void *dirconfig,
774 const char *wrapperpath,
775 const char *extension)
776 {
777 const char *path, *tmp;
778 apr_status_t rv;
779 apr_finfo_t finfo;
780 const char *userdata_key = "fcgid_wrapper_id";
781 wrapper_id_info *id_info;
782 apr_size_t *wrapper_id;
783 fcgid_wrapper_conf *wrapper = NULL;
784 fcgid_dir_conf *config = (fcgid_dir_conf *) dirconfig;

Там же получаем stat файла враппера:
824 /* Is the wrapper exist? */
825 if ((rv = apr_stat(&finfo, path, APR_FINFO_NORM,
826 cmd->temp_pool)) != APR_SUCCESS) {
827 return apr_psprintf(cmd->pool,
828 "can't get fastcgi file info: %s(%s), errno: %d",
829 wrapperpath, path, apr_get_os_error());
830 }
831

И чуть ниже inode от него помещаем в требуемую нам структуру:
832 strncpy(wrapper->args, wrapperpath, _POSIX_PATH_MAX - 1);
833 wrapper->args[_POSIX_PATH_MAX - 1] = '\0';
834 wrapper->inode = finfo.inode;
835 wrapper->deviceid = finfo.device;
836 wrapper->share_group_id = *wrapper_id;
837 *wrapper_id++;
838
839 /* Add the node now */
840 apr_hash_set(config->wrapper_info_hash, extension, strlen(extension),
841 wrapper);
842
843 return NULL;
844 }

Итого, выходит, что идентификация идет по inode враппера, то есть, "число соединений до 1 сайта" это и ничто иное.


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

Открываем файл:
vi fcgid_spawn_ctl.c

Ищем блок:
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process);
200 return 0;
201 }

И корректируем ее до вида (добавляем дамп inode при ошибке spawn нового процесса):
194 /* I need max class proccess count */
195 if (current_node->process_counter >= g_max_class_process) {
196 ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, main_server,
197 "mod_fcgid: too much %s process(current:%d, max:%d, inode:%d), skip the sp awn request",
198 command->cgipath, current_node->process_counter,
199 g_max_class_process, command->inode);
200 return 0;
201 }


И пересобираем mod_fcgid ( debuild -us -uc ) и пробуем вызвать ошибку.

Получаем ошибку в логе:
[Sat Oct 30 04:07:40 2010] [notice] mod_fcgid: too much /var/www/yyyy/data/www/forum.xxxx.ru/xxxxx.php process(current:2, max:2, inode:85541102), skip the spawn request

Теперь смотрим inode враппера:
ls -i /var/www/yyyy/data/php-bin/php
85541102 /var/www/yyyy/data/php-bin/php

Таким образом, исследование кода было проведено верно (но, к слову, не в полной мере, вариант отсутствия wrapper, если он, конечно, возможен, не рассмотрен) :)

Заключение

Параметр конфига, указанный в самом начале поста, регулирует число рабочих процессов для всех сайтов, которые используют один wrapper.


Вот пример такой конфигурации:
[Sat Oct 30 04:07:51 2010] [notice] mod_fcgid: too much /var/www/v001001/data/www/xxxxx.ru/index.php process(current:2, max:2, inode:85541102), skip the spawn request
[Sat Oct 30 04:07:51 2010] [notice] mod_fcgid: too much /var/www/v001001/data/www/yyyyyy.com/index.php process(current:2, max:2, inode:85541102), skip the spawn request

среда, 19 мая 2010 г.

[Wed May 19 19:39:55 2010] [emerg] (13)Permission denied: mod_fcgid: can't get lock, pid: 21627

strace дает следующий результат:
[pid 21841] brk(0xc26000) = 0xc26000
[pid 21841] semop(2555905, 0x7f87e3f84a60, 1) = -1 EACCES (Permission denied)
[pid 21841] write(9, "[Wed May 19 19:45:06 2010] [emerg] (13)Permission denied: mod_fcgid: can't get lock, pid: 21841\n"..., 96) = 96


Причина:

dpkg -l | grep itk
ii apache2-mpm-itk 2.2.6-02-1+lenny2+b3 multiuser MPM for Apache 2.2


Решение - удалить и воткнуть префорк. То есть, mod_fcgid несовместим с Apache mpm_itk.

вторник, 13 апреля 2010 г.

Установка PHP htscanner на Debian - поддержка php_flag в .htaccess для PHP FastCGI / CGI

Офсайт проекта: http://pecl.php.net/package/htscanner

Ставим зависимости:
apt-get install -y php5-dev make patch


cd /usr/src
wget http://pecl.php.net/get/htscanner-0.9.0.tgz
# или зеркало
wget http://fastvps.googlecode.com/svn/trunk/packages/htscanner-0.9.0.tgz
tar -xf htscanner-0.9.0.tgz
cd htscanner-0.9.0
# накладываем патч, без него не будет работать php_flag
wget http://fastvps.googlecode.com/svn/trunk/patches/htscanner.patch
patch -p0 < htscanner.patch # следом накладываем патч для запрета перекрыти memory_limit wget http://fastvps.googlecode.com/svn/trunk/patches/deny_values.patch patch -p0 < deny_values.patch phpize ./configure make



Устанавливаем:
cp modules/htscanner.so /usr/lib/php5/20060613/


Или
make install


Но этого недостаточно, чтобы модуль подключился:
php -m | grep htscanner


Создаем конфиг:
vi /etc/php5/conf.d/htscanner.ini


[htscanner]
extension="htscanner.so"
; The configuration file htscanner needs to scan for php_* directives
config_file=".htaccess"
; The fallback docroot when htscanner can't determine the current docroot
default_docroot="/"
default_ttl=300
; Stop when an error occured in RINIT (no document root, cannot get path_translated,...)
stop_on_error = 0


Теперь создаем в корне сайта .htaccess со следующими строками (поиски по Гуглу и опрос знакомых подтвердили, у htscanner php_flag не работает в принципе):
php_flag register_globals On

но это не сработает почему-то :( А вот такой вариант отлично пашет:

php_value register_globals 1


Обращаю внимание, что после изменения .htaccess необходимо перезапустить рабочие процессы PHP, чтобы изменения применились:
killall -u username


В процессе поиска фикса насткнулся на следующие патчи для htscanner 0.9.0:
http://yourserveradmin.com/ik/htscanner-0.9.0.eol.patch и вот http://blog.hbis.fr/2009/04/02/htscanner-parser-patch/patch-htscanner-parser-20090401/ (как раз, вроде, на мою проблему).

PHP FastCGI + php_admin_value, php_admin_flag, php_value, php_flag

Как известно, эти команды указываются в .htaccess и должны поидее читаться модулем PHP для Апача, но когда последний не используется, а используются, скажем, PHP FastCGI / CGI, то эти директивы будут просто-напросто проигнорированы и эффекта не возымеют.

Но есть проблема - есть фикс! Вот что говорят ребята из Zend: http://kb.zend.com/index.php?View=entry&EntryID=259

А именно:

Using htscanner - htaccess support for PHP
Description: Allow one to use htaccess-like file to configure PHP per directory, just like apache's htaccess.
It is especially useful with fastcgi.


А вот ссылка на этот самый HTScanner: http://pecl.php.net/package/htscanner

Краткое описание от авторов этого самого мегаэкстеншена:
Allow one to use htaccess-like file to configure PHP
per directory, just like apache's htaccess. It is especially useful with fastcgi (ISS5/6/7, lighttpd, etc.).
This package was originally developed by Bart Vanbrabant. Old versions are available
from: http://files.zoeloelip.be/htscanner


Еще есть фича - если у Вас используется FastCGI, но при этом подключен PHP как модуль Апача, то все будет ок - php_* директивы будут проигнорированы, а вот если используется только FastCGI и PHP модуль в принципе отключен, то будет ошибка :) Но тут приходит на модуль модуль mod_fakephp, который подавляет выдачу ошибок при обнаружении опций PHP в .htaccess: http://www.dmi.me.uk/code/apache/mod_fakephp/

За наводку огромный респект arp`у: http://highloaded.blogspot.com/2010/04/htaccess-phpflag-with-fastcgi-on-debian.html и вот еще отличная статья с интересным подходом: http://dromok.ru/?p=104

Вот мой мануал по настройке этого чуда: http://phpsuxx.blogspot.com/2010/04/php-htscanner-debian-phpflag-htaccess.html А вот мануал в моем блоге: http://phpsuxx.blogspot.com/2011/01/modfakephp-debian.html

пятница, 2 апреля 2010 г.

Массовая смена режима работы PHP на FastCGI в ISPManager

Вот так можно получить список всех доменов на сервере:
for i in `/usr/local/ispmgr/sbin/mgrctl -m ispmgr wwwdomain | tr '=' ' ' | awk '{print $2}'`; do echo $i ; done


А вот так определенному www домену можно сменить режим работы PHP на FastCGI:
/usr/local/ispmgr/sbin/mgrctl -m ispmgr wwwdomain.edit elid=xxx.com alias=www.xxx.com php=phpfcgi admin=xxx@xxx.com ip=x.x.x.x sok=ok


А вот скрипт для автоматической смены:

for i in `/usr/local/ispmgr/sbin/mgrctl -m ispmgr wwwdomain | tr '=' ' ' | awk '{print $2}'`; do /usr/local/ispmgr/sbin/mgrctl -m ispmgr wwwdomain.edit elid=$i alias=www.$i php=phpfcgi admin=xxx@xxx.com ip=x.x.x.x sok=ok ; done

пятница, 12 февраля 2010 г.

Как включить register_globals на сервере с ISPManager и PHP FastCGI?

Заходите в "Инструменты" -> "Менеджер файлов". Далее в домашней папке входите в папку php-bin и там видите php.ini, куда требуется добавить строку:
register_globals = On


Но ISP выдаст "Can't open file '/var/www/v001022/data/php-bin/php.ini' for writing", хотя права на файл 400 и владельцем указан владелец аккаунта :( Так что делайте это через FTP либо попросите сделать это саппорт.

Для саппорта нужно сделать следующее:
echo "register_globals = On" >> /var/www/v001022/data/php-bin/php.ini
killall -u v001022


После этого PHP воркеры благополучно погибнут и запустятся с новыми настройками.

Либо после внесения изменений в конфиг необходимо зайти в панель управления ISPManager и открыть настройки указанного www домена и просто их сохранить ничего не меняя (это вызовет релоад Апача, что необходимо для применения настройки из пользовательского php.ini).

среда, 20 января 2010 г.

Установка PHP как FastCGI на панели управления хостингом ISPManager, Debian 5 Lenny

В новых версиях все намного проще! Просто идете в "Возможности", выбираете там "Модуль FastCGI для веб-сервера Apache" и нажимаете на "кнопку с дисками" для установки и ожидаете, пока он поставится на панель. После этого должна появиться опция PHP как FastCGI при создании www-доменов.

Ставим:
apt-get install -y libapache2-mod-fcgid


Перезапускаем апача:
/etc/init.d/apache2 restart


Перезапускаем панель ISPManager:
killall -9 -r ispmgr


Готово, теперь в настройках www домена должна появится возможность "Php как FastCGI".

Но в последних версиях этот фикс не сработает, ибо в панели опять что-то сломали!

Открываем конфиг:
vi /usr/local/ispmgr/etc/ispmgr.conf


И в самый низ добавляем следующее:
Option ForcePhpFCgid



Перезапускаем панель ISPManager:
killall -9 -r ispmgr


И вот теперь уж точно должно появиться :)

Новинка в mod_fcgid 2.3.5 - показ статуса процессов в server-status

Display information about active processes in the server-status page. [Ryan Pan]



(c) CHANGES-FCGID

Куда пропал оф сайт mod_fcgid http://fastcgi.coremail.cn/doc.htm ?

Последнюю неделю пытаюсь зайти на http://fastcgi.coremail.cn/doc.htm, но обламываюсь :( Думал, что просто лежит. Оказывается нет:
mod_fcgid was created by Ryan Pan (Pan Qingfeng, pqf or 潘庆峰) in 2004 as a new FastCGI implementation, and was granted to the ASF as an Apache HTTP Server subproject in 2009, shepherded by Chris Darroch (chrisd).


(с) http://httpd.apache.org/mod_fcgid/

воскресенье, 3 января 2010 г.

Установка eAccelerator на Debian 5 Lenny для PHP в FastCgi режиме

На офсайте говорится "eAccelerator only works with mod_php or php in fastcgi mode. It can't be used in cgi or cli because eAccelerator needs to set up shared memory, and this can only be done when all php instances that need to access it are forks of the first process".

Что по-русски означает, что eAccelerator работает только, если PHP подключен как модуль Апача либо как FastCGI.

Будем ставить версию 0.9.6.1

Ставим все необходимое для сборки:

apt-get install -y php5-dev bzip2 make


Компилируем:


cd /usr/src
wget http://bart.eaccelerator.net/source/0.9.6.1/eaccelerator-0.9.6.1.tar.bz2
tar -xf eaccelerator-0.9.6.1.tar.bz2
cd eaccelerator-0.9.6.1
phpize
./configure
make install


Очищаем систему после сборки
apt-get remove php5-dev
cd
rm -rf /usr/src/eaccelerator-0.9.6.1
rm -f /usr/src/eaccelerator-0.9.6.1.tar.bz2


Кстати, крайне рекомендую обратить внимание на файлик control.php в дистрибутиве, который предназначен для управления и мониторинга eAccelerator :) (спасибо Котеровским наблам, где это упомянуто)

--prefix тут, к сожалению, не работает, т.к. configure берет путь до библиотек из:

php-config --extension-dir
/usr/lib/php5/20060613



Создаем конфиг файл:

vi /etc/php5/conf.d/eaccelerator.ini


Вариантов подключения к PHP два - Zend Extension и обычное расширение, мне почему-то второй больше импонирует.

Вот стандартный конфиг:

extension="eaccelerator.so"
# eaccelerator.shm_size="16" # иначе получите проблемы на своем VPS
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"


А вот мой оптимизированный:

extension="eaccelerator.so"
; размер shm памяти в мегабайтах
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
; памяти у нас много, будем кэшировать в ней
eaccelerator.shm_only="1"
; рекомендую отлючить
eaccelerator.compress="0"
eaccelerator.compress_level="9"


Создаем папки для кэша (тут, как понимаете, будут проблемы с FastCGI, т.к. в нем скрипты работают от имени юзеров, а не от имени Апача, как это победить - я хз пока что). Кстати, в случае SHM памяти все будет очень безопасно по причине, что shm блоки будут создаваться от имени пользователя, от которого запускается скрипт. Так что самый лучший вариант в случае FastCGI - отключение файлового кэша и расположение скомпилированного кода только в shm.

Это в случае использования только shm не требуется:

mkdir /tmp/eaccelerator
chmod 0777 /tmp/eaccelerator


А испытать работоспособность можно командой:

php -m | grep eAcc
eAccelerator


И, наконец, перезапускаем Апача:

/etc/init.d/apache2 restart


Также в результате может сломаться phpmyadmin, фиксить его так: http://phpsuxx.blogspot.com/2009/11/g-phpmyadmin.html

Основано на: http://www.eaccelerator.net/wiki/InstallFromSource

Обращаю внимание, в мане баг! В Дебияне /tmp/eaccelerator будет удалена при ребуте.

Также обращаю внимание, что при устанвоке размера памяти SHM более 32 бегабайт возможен облом в виде:
eAccelerator: Could not allocate 67108864 bytes, the maximum size the kernel allows is 33554432 bytes. Lower the amount of memory request or increase the limit in /proc/sys/kernel/shmmax.

Это, конечно, тоже фиксится, но нужно немного подтюнить ядро :)

вторник, 1 декабря 2009 г.

mod_fcgid: read data timeout in 40 seconds


vi /etc/httpd/conf.d/fcgid.conf


или (Debian)


vi /etc/apache2/mods-available/fcgid.conf



IPCCommTimeout 300



/etc/init.d/httpd restart

Установка PHP как FastCGI на панели управления хостингом ISPManager, CentOS

Для начала ставим репозиторий, где расположены все требуемые нам пакеты:
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm


Ставим mod_fcigd:
yum install mod_fcgid -y


Открываем файл конфига:
vi /etc/httpd/conf.d/fcgid.conf


и комментируем в нем строку:
### LoadModule fcgid_module modules/mod_fcgid.so


Открываем файл:
vi /etc/httpd/conf/httpd.conf


Ищем блок "LoadModules" и вставляем туда строку:
LoadModule fcgid_module modules/mod_fcgid.so


Открываем конфиг PHP:
vi /etc/php.ini


ОБЯЗАТЕЛЬНО комментируем строку (иначе будут косяки с сессиями):
;session.save_path = "/var/lib/php/session"


Перезапускам Апача:
/etc/init.d/httpd restart


Перезапускаем панель ISPManager:
killall -9 -r ispmgr


Готово, теперь в настройках www домена должна появится возможность "Php как FastCGI".