Патч для php-cgi, позволяющий конфигурировать значение listen backlog

Задание listen backlog через переменную окружения PHP_FCGI_LISTEN_BACKLOG

По умолчанию значение listen backlog в -cgi жёстко задано — 128. Это означает, что не сможет обработать более 128 запросов одновременно (точнее, что очередь запросов не сможет превысить данного значения). Я столкнулся с тем, что 128 — это мало.

Для тех, кто столкнулся с данной проблемой, но по каким-либо причинам не хочет/не может поставить php-fpm (в котором backlog конфигурируется), я сделал небольшой .

[-]
Download cgi-main.c.diff
--- php.orig/sapi/cgi/cgi_main.c.orig   2009-06-09 13:29:39.000000000 +0000
+++ php/sapi/cgi/cgi_main.c 2010-01-03 04:44:34.000000000 +0000
@@ -1523,7 +1523,15 @@
 
 #if PHP_FASTCGI
    if (bindpath) {
-       fcgi_fd = fcgi_listen(bindpath, 128);
+       int backlog = 128;
+       if (getenv("PHP_FCGI_LISTEN_BACKLOG")) {
+           backlog = atoi(getenv("PHP_FCGI_LISTEN_BACKLOG"));
+           if (backlog < 0) {
+               backlog = 128;
+           }
+       }
+
+       fcgi_fd = fcgi_listen(bindpath, backlog);
        if (fcgi_fd < 0) {
            fprintf(stderr, "Couldn't create FastCGI listen socket on port %s\n", bindpath);
 #ifdef ZTS

Применять к файлу sapi/cgi/cgi_main.c.

Что даёт: значение backlog можно задавать в переменной окружения PHP_FCGI_LISTEN_BACKLOG.

Проверялось на PHP 5.2.10-2ubuntu6.3 (Ubuntu 9.10).

Установка в Debian/Ubuntu:

[-]
View Code Bash
mkdir php && cd php
apt-get source php5-cgi
sudo apt-get install devscripts build-essential wget
sudo apt-get build-dep php5-cgi
cd php5-*
QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null push -a
wget http://d.sjinks.pro/listen-backlog-env-var.patch -O debian/patches/listen-backlog-env-var.patch
QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null import debian/patches/listen-backlog-env-var.patch
QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null push -a
QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null pop -a
debuild clean
debuild -i -us -uc -b

Практические результаты: при помощи ab генерировалась сильная нагрузка (DoS) на сервер (10,000 запросов в 200 параллельных потоков):

[-]
View Code Bash
ab -n 10000 -c 200 http://example.com/

Стандартный PHP смог обработать 2,275 запросов из 10,000 — остальные запросы были отвергнуты (502 Bad Gateway).

После применения патча и

[-]
View Code Bash
echo 2048 > /proc/sys/net/core/somaxconn
export PHP_FCGI_LISTEN_BACKLOG=1024

и перезапуска, PHP смог обработать все запросы.

Изменилось всего-то 9 строк кода, а какой результат!

Автор: ; опубликовано в: C/C++, PHP; метки: C/C++, FastCGI, PHP, патч
3
Янв
2010

RSS Комментарии к статье «Патч для php-cgi, позволяющий конфигурировать значение listen backlog» (10)  »

  1. mamuka

    Владимир подскажите пожалуйста как правильно это всё проделать?
    1. Берём и копируем код – cgi-main.c.diff и вставляем его в файл sapi/cgi/cgi_main.c.?
    (вставлять в любое место?)
    2. Куда вставить View Code Bash?

  2. [-]
    View Code Text
    Hmm...  Looks like a unified diff to me...
    The text leading up to this was:
    --------------------------
    |--- php.orig/sapi/cgi/cgi_main.c.orig  2009-06-09 13:29:39.000000000 +0000
    |+++ php/sapi/cgi/cgi_main.c    2010-01-03 04:44:34.000000000 +0000
    --------------------------
    Patching file sapi/cgi/cgi_main.c using Plan A...
    Hunk #1 failed at 1523.
    1 out of 1 hunks failed--saving rejects to sapi/cgi/cgi_main.c.rej
    done
    • Проверьте концы строк, при загрузке патча они могут быть досовскими, а не юниксовыми.

      И что находится в sapi/cgi/cgi_main.c.rej?

      • Патч скачал по sftp на сервер.. попробую посмотреть с BOM или без него..

        PHP5, последняя версия

        В rej:

        [-]
        View Code Diff
        ****************
        *** 1523,1529 ****
         
         #if PHP_FASTCGI
            if (bindpath) {
        -       fcgi_fd = fcgi_listen(bindpath, 128);
        +       int backlog = 128;
        +       if (getenv("PHP_FCGI_LISTEN_BACKLOG")) {
        +           backlog = atoi(getenv("PHP_FCGI_LISTEN_BACKLOG"));
        +           if (backlog < 0) {
        +               backlog = 128;
        +           }
        +       }
        +
        +       fcgi_fd = fcgi_listen(bindpath, backlog);
                if (fcgi_fd < 0) {
                    fprintf(stderr, "Couldn&#039;t create FastCGI listen socket on port %s\n", bindpath);
         #ifdef ZTS
        • Там не BOM, там концы строк могут быть другими — \r\n (как в DOS/Windows), а не \n (как в *nix).

          Попробуйте натравить на патч dos2unix.

  3. попробовал патч – помогло, но неполностью, жил немного дольше чем обычно при нагрузке, но потом все равно было 499, 502 и 504
    php 5.3.1, федора fc12.x86_64
    увеличивал somaxconn, backlog и т.д. и т.п.
    помог случай
    все работает отлично, если скомпилировать php еще с опцией –enable-debug
    так что рекомендую всем кому патч не помог полностью

    • доразобрались – с опцией enable-debug не запускался eaccelerator и все работало отлично
      а проблемы оказывается были из-за него
      если скачать исходники eaccelerator и собрать нормально с php, то уже и опция disable-debug прокатит для нормальной работы

      • если скачать исходники eaccelerator и собрать нормально с php, то уже и опция disable-debug прокатит для нормальной работы

        Всё время так и делаю.

        PS — а на 5.3.x патч без проблем накладывается? Я только на 5.2.x проверял.

Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.

Оставить комментарий к записи «Патч для php-cgi, позволяющий конфигурировать значение listen backlog»

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя

गते गते पारगते पारसंगते बोधि स्वाहा