Патч, добавляющий поддержку php-fpm в порт lang/php5

Набросал небольшой патч, добавляющий в порт php 5.3 поддержку php-fpm. Из недостатков — требует наличие svn клиента для загрузки патчей с репозитария svn.php.net. Зато в теории будет работать для любой стабильной версии порта в пределах ветки 5.3.x.

Установка очень простая:

cd /usr/ports/lang/php5
fetch http://sav.ecom24.ru/freebsd/fpm.patch
patch < fpm.patch
make config install clean

Сам патч:

--- Makefile    2010-06-17 07:59:24.414207380 +0000
+++ Makefile    2010-06-17 08:56:48.418613806 +0000
@@ -43,7 +43,8 @@ OPTIONS=      CLI "Build CLI version" on \
                SUHOSIN "Enable Suhosin protection system" on \
                MULTIBYTE "Enable zend multibyte support" off \
                IPV6 "Enable ipv6 support" on \
-               MAILHEAD "Enable mail header patch" off
+               MAILHEAD "Enable mail header patch" off \
+               FPM "Enable PHP-FPM patch" off

 CONFLICTS=     php4-4* php5-pcre-* php5-spl-*

@@ -51,6 +52,13 @@ MAN1=                php-config.1 phpize.1

 .include 

+.if defined(WITH_FPM)
+USE_RC_SUBR=   php-fpm.sh
+LIB_DEPENDS+=  event:${PORTSDIR}/devel/libevent
+BUILD_DEPENDS+=        svn:$(PORTSDIR)/devel/subversion
+CONFIGURE_ARGS+=--enable-fpm --with-fpm-log=/var/log/php-fpm.log --with-fpm-pid=/var/run/php-fpm.pid
+.endif
+
 PATCH_DIST_STRIP=      -p1

 .if !defined(WITHOUT_SUHOSIN)
@@ -136,9 +144,16 @@ CONFIGURE_ARGS+=--disable-ipv6
 post-patch:
        @${TOUCH} ${WRKSRC}/ext/php_config.h
        @${REINPLACE_CMD} "s|^\(extension_dir\)|; \1|" ${WRKSRC}/php.ini-*
+       @(svn export http://svn.php.net/repository/php/php-src/branches/PHP_5_3/sapi/fpm ${WRKSRC}/sapi/fpm)

 pre-configure:
        @${CAT} ${WRKSRC}/acinclude.m4 ${WRKSRC}/build/libtool.m4 > ${WRKSRC}/aclocal.m4
+       @(cd ${WRKSRC} && ./buildconf --force)
+
+post-configure:
+.if defined(WITH_FPM)
+       @${REINPLACE_CMD} "s|/usr/local/var|/var|" ${WRKSRC}/sapi/fpm/php-fpm.conf
+.endif

 post-build:
        @${ECHO_CMD} "PHP_VER=5" > ${WRKDIR}/php.conf
--- files/php-fpm.sh.in 1970-01-01 00:00:00.000000000 +0000
+++ files/php-fpm.sh.in 2010-06-17 09:05:07.600963518 +0000
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# PROVIDE: php-fpm
+# REQUIRE: NETWORKING SERVERS
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable php-fpm:
+# php_fpm_enable (bool):      Set to "NO" by default.
+#                             Set it to "YES" to enable php-fpm
+# php_fpm_config (str):       Set to "" by default.
+#                             Define your php-fpm configuration file here.
+
+. /etc/rc.subr
+
+name="php_fpm"
+rcvar=`set_rcvar`
+
+load_rc_config $name
+
+: ${php_fpm_enable="NO"}
+: ${php_fpm_pidfile="/var/run/php-fpm.pid"}
+: ${php_fpm_config="%%PREFIX%%/etc/php-fpm.conf"}
+
+command="%%PREFIX%%/sbin/php-fpm"
+pidfile=${php_fpm_pidfile}
+reload_precmd="php_fpm_prereload"
+quit_cmd="php_fpm_quit"
+
+[ -n "$php_fpm_config" ] && php_fpm_flags="--fpm-config $php_fpm_config"
+
+php_fpm_prereload()
+{
+       sig_reload=USR2
+}
+
+php_fpm_quit()
+{
+       sig_stop=QUIT
+       run_rc_command stop
+}
+
+extra_commands="reload quit"
+run_rc_command "$1"

Организация горячего кэширования статики в nginx

В определенных ситуациях требуется быстро раздавать фиксированный набор статических файлов, например при раздаче swf файлов flash/flex приложений.
Для того, чтобы снизить нагрузку на диски и уменьшить время реакции, можно организовать горячее кэширование файлов в оперативной памяти:

Создадим хранилище для кэша на md диске:

mkdir /var/tmp/nginx
chown www:www /var/tmp/nginx
echo "md /var/tmp/nginx mfs rw,-s128m,late 2 0" >> /etc/fstab
mount /var/tmp/nginx

Организуем локальный сервер для раздачи статики, с которого будет заполняться кэш:

server
{
    listen 127.0.0.1:80;
    root /usr/local/www/site;
}

В контексте http описываем зону кэширования:

proxy_cache_path /var/tmp/nginx/store levels=1:2 keys_zone=STATIC:10m inactive=1d max_size=128m;

В контексте server добавляем location для статики, которую будем кэшировать:

location ~\.swf$ {
    proxy_pass http://127.0.0.1:80;
    expires 30d;
    proxy_intercept_errors on;
    proxy_cache STATIC;
    proxy_cache_min_uses 1;
    proxy_cache_valid 1d;
    proxy_ignore_client_abort on;
    proxy_temp_path /var/tmp/nginx/tmp;
    proxy_cache_use_stale updating;
}

Перегружаем сервер и запрашиваемые swf файлы начинают кэшироваться на md диске:

/usr/local/etc/rc.d/nginx reload

nginx vs DDoS: accept-фильтры во FreeBSD

Вот что пишет о механизме accept-фильтров автор web-сервера nginx Игорь Сысоев:

Два года назад во FreeBSD появились accept-фильтры. Они позволяют не передавать в accept() пришедшее соединение до тех пор, пока не придёт первый пакет с данными (фильтр dataready) или заголовок HTTP-запроса (фильтр httpready). Использование фильтров в Apache (а в нём они поддерживаются, начиная с версии 1.3.14) позволяет уменьшить число процессов. В серверах, использующих select(), poll() или kqueue(), например, в thttpd-2.22, фильтры уменьшают число открытых файлов. И наконец, в обоих случаях accept-фильтры уменьшают число переключений контекста процесса.

Таким образом, использование данного инструментария позволить перенести обработку части запросов в ядро и снизить общую загрузку сервера. Читать далее nginx vs DDoS: accept-фильтры во FreeBSD

Хранение сессий PHP в memcached

Данные всех пользовательских сессий php по умолчанию складывает в особые файлы во временной директории. Количество этих файлов пропорционально количеству пользователей, работающих с проектом.

При определенном уровне нагрузки это приведет к тому, что даже простое открытие файла сессии будет длиться секунду и дольше. Что неизбежно привезет к зависанию клиентских запросов в пуле PHP-FastCGI и появлению ошибок 502 Bad Gateway при попытке открыть любой пхп скрипт — только лишь потому, что большинство воркеров будут заняты открытием файлов сессий.
Читать далее Хранение сессий PHP в memcached

nginx vs DDoS: выносим мусор

Одна из самых простых разновидностей ботнета — сеть, участники которой подключаются к серверу на 80 порт и тупо запрашивают /. Либо вообще ничего не запрашивают и висят, пока сервер не скинет их по client_header_timeout (по умолчанию 60 секунд).
В логах это выглядит следующим образом:

85.192.188.150 - - [01/Dec/2009:09:21:01 +0300] "-" 400 0 "-" "-"
85.192.188.150 - - [01/Dec/2009:09:21:01 +0300] "-" 400 0 "-" "-"
85.192.188.150 - - [01/Dec/2009:09:21:01 +0300] "-" 400 0 "-" "-"
85.192.188.150 - - [01/Dec/2009:09:21:01 +0300] "-" 400 0 "-" "-"
85.192.188.150 - - [01/Dec/2009:09:21:01 +0300] "-" 400 0 "-" "-"

Читать далее nginx vs DDoS: выносим мусор