Подтвердить что ты не робот

Nginx и php-fpm: не могут избавиться от ошибок 502 и 504

У меня есть ubuntu-сервер и довольно загруженный веб-сайт. Сервер:

  • Посвящается nginx, использует php-fpm (без apache), mysql находится на другой машине
  • Имеет 8 ГБ оперативной памяти.
  • Получает около 2000 запросов в секунду.

Каждый процесс php-fpm потребляет около 65 МБ ОЗУ в соответствии с командой top:

top command

Свободная память:

[email protected]:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          7910       7156        753          0        284       2502
-/+ buffers/cache:       4369       3540
Swap:         8099          0       8099

ПРОБЛЕМА

В последнее время у меня большие проблемы с производительностью. Очень большое время отклика, очень много Gateway Timeouts и по вечерам, когда загрузка становится высокой, 90% пользователей просто видят "Сервер не найден" вместо веб-сайта (я не могу воспроизвести это)


ЖУРНАЛОВ

Журнал ошибок Nginx заполнен следующими сообщениями:

2012/07/18 20:36:48 [error] 3451#0: *241904 upstream prematurely closed connection while reading response header from upstream, client: 178.49.30.245, server: example.net, request: request: "GET /readarticle/121430 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9001", host: "example.net", referrer: "http://example.net/articles"

Я попытался переключиться на unix-сокет, но все равно получаю следующие ошибки:

2012/07/18 19:27:30 [crit] 2275#0: *12334 connect() to unix:/tmp/fastcgi.sock failed (2: No such file or directory) while connecting to upstream, client: 84.
237.189.45, server: example.net, request: "GET /readarticle/121430 HTTP/1.1", upstream: "fastcgi://unix:/tmp/fastcgi.sock:", host: "example.net", referrer: "http
://example.net/articles"

И журнал php-fpm полон:

[18-Jul-2012 19:23:34] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there  are 0 idle, and 75 total children

Я пытался увеличить заданные параметры до 100, но это все еще кажется недостаточным.


конфиги

Вот моя текущая конфигурация

PHP-FPM

listen = 127.0.0.1:9001
listen.backlog = 4096
pm = dynamic
pm.max_children = 130
pm.start_servers = 40
pm.min_spare_servers = 10
pm.max_spare_servers = 40
pm.max_requests = 100

Nginx

worker_processes  4;
worker_rlimit_nofile 8192;
worker_priority 0;
worker_cpu_affinity 0001 0010 0100 1000;

error_log  /var/log/nginx_errors.log;

events {
    multi_accept off;
    worker_connections  4096;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log off;
    sendfile        on;
    keepalive_timeout  65;
    gzip  on;

    # fastcgi parameters
    fastcgi_connect_timeout 120;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 1000;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

    client_max_body_size 128M;

    server {
        server_name example.net;
        root /var/www/example/httpdocs;
        index index.php;
        charset utf-8;
        error_log /var/www/example/nginx_error.log;

        error_page 502 504 = /gateway_timeout.html;

        # rewrite rule
        location / {
            if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php?path=$1 last;
            }
        }
        location ~* \.php {
            fastcgi_pass 127.0.0.1:9001;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

Я был бы очень благодарен за любые советы о том, как определить проблему и какие параметры я могу настроить, чтобы исправить это. Или, может быть, 8 ГБ оперативной памяти недостаточно для такой нагрузки?

4b9b3361

Ответ 1

Несколько вопросов. Все еще стоит исправить их с таким загруженным сайтом. На данный момент MySQL может быть основной причиной. Но в долгосрочной перспективе вам нужно больше работать.

Кэширование

Я вижу один из ваших сообщений об ошибке, показывающий запрос на получение php upstream. Это не очень хорошо выглядит на таком высоком участке трафика (2000 р/с, как вы упомянули). Эта страница (/readarticle/121430) кажется полностью кэшируемой страницей. Во-первых, вы можете использовать nginx для кеширования таких страниц. Проверьте кеш fastcgi

GET /readarticle/121430

PHP-FPM

pm.max_requests = 100

Значение означает, что процесс будет убит мастером php-fpm после обслуживания 100 запросов. php-fpm использует это значение для борьбы с утечками памяти сторонних производителей. Ваш сайт очень занят, с 2000р/с. Максимальные дочерние процессы - 130, каждый может обслуживать не более 100 запросов. Это означает, что после 13000/2000 = 6,5 секунд все они будут переработаны. Это слишком много (20 процессов убивают каждую секунду). Вы должны, по крайней мере, начинать со значения 1000 и увеличивать это число до тех пор, пока не увидите утечку памяти. Кто-то использует 10 000 в производстве.

nginx.conf

  • Проблема 1:

        if (!-e $request_filename) {
            rewrite ^(.*)$ /index.php?path=$1 last;
        }
    

    следует заменить более эффективными try_files:

        try_files $uri /index.php?path=$uri;
    

Вы сохраняете дополнительный блок , если, и соответствие правила перезаписи regex.

  • Проблема 2: использование unix-сокета позволит вам сэкономить больше времени, чем использовать ip (около 10-20% от моего опыта). Именно поэтому php-fpm использует его по умолчанию.

  • Проблема 3: Возможно, вас заинтересовала настройка keepalive соединений между nginx и php-fpm. Пример представлен здесь на официальном сайте nginx.

Ответ 2

Мне нужно увидеть ваши настройки php.ini, и я не думаю, что это связано с MySQL, так как вы получаете ошибки сокета, как это выглядит. Кроме того, это то, что начинает происходить через какое-то время или это происходит сразу после перезагрузки сервера?

Попробуйте перезапустить демон php5-fpm и посмотреть, что происходит, когда вы заканчиваете свой журнал ошибок.

Проверьте файл php.ini и все ваши fastcgi_params, обычно находящиеся в /etc/nginx/fastcgi _params. Существует множество примеров того, что вы пытаетесь сделать.

Кроме того, активировано расширение кэширования apc php?

Это будет выглядеть в вашем файле php.ini, если вы на стеке лампы:

расширение = apc.so
....
apc.enabled = 0

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

Ответ 3

Настройка микрокаши nginx также поможет. Который будет обслуживать один и тот же ответ в течение нескольких секунд.

http://seravo.fi/2013/optimizing-web-server-performance-with-nginx-and-php имеет некоторую хорошую информацию о производительности nginx. Лично следовало за этим, и я очень доволен.

Ответ 4

ради ответа на этот вопрос:

You should check your MySQL server. Probably it overloaded or it limits count of parallel MySQL connections. You should find the bottleneck. And according to your top screenshot it doesn't look like either RAM or CPU, then it most likely I/O. - @VBrat

Вещи, которые вы, возможно, захотите сделать в будущем:

1- Увеличьте объем оперативной памяти.

2- использовать кеш. см. в этой статье о том, как кеш может ускорить ваш сайт.

3- уменьшить количество выполняемых запросов.

Ответ 5

  • Настройка расширения APC для PHP (check/configure)
  • MySQL - проверьте конфигурацию, индексы, медленные запросы
  • Установите и настройте лак. Это может кэшировать запросы страниц и быть весьма полезным в уменьшении количества запросов php и запросов mysql, которые вам нужно сделать. Это может быть сложно с cookies/ssl, но в противном случае это не слишком сложно и очень полезно для запуска.