Назад | Перейти на главную страницу

Настройте php5-fpm для множества одновременно работающих пользователей

РЕДАКТИРОВАТЬ: По запросу anthonysomerset добавлены некоторые конфигурации и уточнение, сколько «много».

РЕДАКТИРОВАТЬ 2: В конфигурацию nginx добавлен fastcgi_cache, предложенный SleighBoy.

Я запускаю сервер для сайта друга, который время от времени получает большие всплески трафика, около 200-300 одновременных пользователей. Между пиками на сервере около 70-80 одновременных пользователей, и он без проблем обрабатывает трафик.

На сайте запущен WordPress с W3 Total Cache на сервере с Debian Squeeze, nginx, PHP5-FPM + APC (128 МБ), MySQL 5, memcached (128 МБ) и Varnish (1 ГБ). Сумма в парентезисе - это то, сколько я выделил для их соответствующего кеша. Память никогда не превышает 1,8 ГБ, но она может быть немного переполнена. Хотя обычно не вызывает проблем ...

Проблема всегда в том, что PHP5-FPM на какое-то время использует 100% ЦП, а затем просто дает сбой, в результате чего nginx выдает 502 ошибки. Журнал предлагает увеличить максимальное количество детей, но я думаю, что я достиг предела количества детей, которое может обработать сервер. Я бегал с pm.max_requests на 0 (неограниченно), но теперь установите его на 1000, чтобы проверить, может ли время от времени возрождение детей помочь.

/etc/php5/fpm/pool.d/www.conf

[www]
listen = /var/run/php5-fpm.sock

user = www-data
group = www-data

pm = dynamic
pm.max_children = 200
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 60
pm.max_requests = 1000

/etc/nginx/nginx.conf

user www-data;
worker_processes 8;
pid /var/run/nginx.pid;

events {
        worker_connections 1024;
}

http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_comp_level 9;
        gzip_buffers 16 8k;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        fastcgi_cache_path /var/cache/nginx levels=1:2
        keys_zone=PHP5FPMCACHE:10m
        inactive=5m;

        fastcgi_cache_key "$scheme$request_method$host$request_uri";

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

/etc/nginx/sites-available/website.com

upstream php5-fpm {
    server unix:/var/run/php5-fpm.sock;
}

server {
        server_name website.com *.website.com;
        server_name_in_redirect off;
        root /var/www/website.com;
        listen 8080;
        client_max_body_size 64M;
        access_log /var/log/nginx/website.com.access.log;
        error_log /var/log/nginx/website.com.error.log;

        keepalive_timeout 75;

        location / {
                index index.php;
                rewrite ^.*/files/(.*) /wp-includes/ms-files.php?file=$1 last;
                if (!-e $request_filename) {
                        rewrite ^(.+)$ /index.php?q=$1 last;
                }

        }

        location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
                expires 30d;
                access_log off;
        }

        location ~ \.php$ {
                fastcgi_pass php5-fpm;
                fastcgi_cache   PHP5FPMCACHE;
                fastcgi_cache_valid   200 302  1h;
                fastcgi_cache_valid   301      1d;
                fastcgi_cache_valid   any      1m;
                fastcgi_cache_min_uses  1;
                fastcgi_cache_use_stale error  timeout invalid_header http_500;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
        }

}

/etc/varnish/website.vcl

backend default {
.host = "127.0.0.1";
.port = "8080";
}

sub vcl_recv {
# Normalize Content-Encoding
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
        }
    }
# Remove cookies and query string for real static files
    if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$") {
       unset req.http.cookie;
       set req.url = regsub(req.url, "\?.*$", "");
    }
# Remove cookies from front page
    if (req.url ~ "^/$") {
       unset req.http.cookie;
    }
}

Это VPS с 4 ядрами и гиперпоточностью (т.е. «8 ядер») и 2 ГБ оперативной памяти. Я знаю, что аппаратный узел (физический сервер) далеко не забронирован и почти не используется (поскольку я работал в хостинговой компании около месяца назад), так что это в значительной степени выделенный сервер.

Если вам нужны какие-либо спецификации, просто спросите.

APC и nginx fastcgi_cache собираюсь вам очень помочь.

Я подозреваю, что ваш кеш лака не кэширует достаточно хитов

вот что я бы сделал в вашей ситуации:

Уменьшите количество дочерних элементов php до 100 или даже 50 (если лак выполняет свою работу должным образом, они вам не нужны), а также удалите строку с максимальным количеством запросов, чтобы процессы php не возрождались слишком быстро и, таким образом, предотвращали слишком быструю очистку APC, что является тоже плохо

также IF не подходит для nginx - http://wiki.nginx.org/IfIsEvil

Я бы изменил эту строку:

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

кому:

try_files $uri $uri/ /index.php?$args;

Если ваша версия nginx поддерживает его (почти наверняка, если ваша версия nginx> 0.7.51, значит, она поддерживается)

вам также следует взглянуть на вставку правил w3tc nginx прямо в ваш файл vhost, чтобы включить правильное расширенное кэширование страниц на диске (что быстрее, чем кеширование APC с nginx)

Взгляните на следующий лак vcl, который я использую для сайтов - вам нужно будет прочитать и отредактировать несколько вещей для вашего веб-сайта - он также предполагает, что это только сайты WP на сервере и только 1 сайт на сервере, он может легко изменить для других сайтов (см. раздел cookie)

общий vcl: https://gist.github.com/b7332971a848bcb7ecef

С этой конфигурацией я бы поспорил, чтобы удалить fastcgi_cache, чтобы предотвратить любые возможные проблемы с цепочкой кеша, из-за чего попытка найти какие-либо ненужные устаревшие записи кеша сложнее

также скажите w3tc, что varnish - 127.0.0.1, и он очистит его за вас;)

Я развернул это на сервере в среду вечером (с некоторыми модификациями для домена), который обрабатывал 2500 активных посетителей сайта, он снизил нагрузку до менее 1, а приблизительное количество запущенных дочерних php было около 10-20 (это число зависит от количество вошедших в систему пользователей и другие факторы, такие как файлы cookie) на этом сервере было гораздо больше оперативной памяти, но принцип тот же, вы должны легко справляться с количеством посетителей, которых вы получаете на пике