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

Сбой сервера (тайм-аут шлюза 504) при 100 одновременных пользователях при использовании nginx и php5-fpm

У нас есть VPS-сервер, предназначенный для одного веб-сайта. Кажется, что изо дня в день он работает нормально (скажем, 20-50 одновременных пользователей), но как только мы получаем около 90+ одновременных пользователей, сервер начинает аварийно завершать работу / тайм-аут. Он начнет показывать ошибку времени ожидания шлюза 504 nginx.

Ранее в этом году у нас были проблемы, когда загрузка некоторых страниц с большим объемом данных занимала около 7 секунд, которые нам удалось решить на 90% за счет оптимизации запросов mysql и использования кеша myqsl. Однако, похоже, это не помогает!

Когда я говорю, что данные тяжелые, он загружает около 5000 записей из БД через фреймворк.

Сервер работает под управлением Ubuntu 15.10 с 4 процессорами и 4 ГБ памяти. Mysql находится на собственном сервере с 1 ГБ памяти. Похоже, что сервер mysql не справляется с нагрузкой на 30% даже при 100 пользователях.

Mysql настроен на 64 МБ query_cache_size и 6 МБ query_cache_limit

У нас установлен APC, но в целом это не имеет большого значения

Это наш nginx.conf

user www-data;
worker_processes 4;
pid /run/nginx.pid;

events {
    worker_connections 1024;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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


    client_body_buffer_size     32k;
    client_header_buffer_size   8k;
    large_client_header_buffers 8 64k;

    #client_body_buffer_size 10K;
    #client_header_buffer_size 1k;
    client_max_body_size 12m;
    #large_client_header_buffers 2 1k;


    fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=microcache:100m inactive=10m max_size=1024m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";


    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

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

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";
    gzip_comp_level 3;
    gzip_vary on;
    gzip_proxied any;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;


    ##
    # Virtual Host Configs
    ##

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

Это серверный блок

server {
    listen 80 default;
    server_name www.website.com;

    root /var/www/website.com/httpdocs;
    index index.php index.html index.htm;

    location / {
            try_files $uri @handler;
    }

    error_page 404 /assets/error-404.html;
    error_page 500 /assets/error-500.html;


    location @handler {
            expires off;

            include fastcgi_params;
            fastcgi_pass unix:/var/run/php5-fpm.sock;

            # fastcgi caching

            #Cache everything by default
            set $no_cache 0;

            if ($request_method !~ ^(GET|HEAD)$) {
                set $no_cache "1";
            }

            #Don't cache the following URLs
            if ($request_uri ~* "/(admin/|member/)")
            {
                    set $no_cache 1;
            }

            #fastcgi_no_cache $no_cache;
            #fastcgi_cache_bypass $no_cache;
            #fastcgi_cache microcache;
            #fastcgi_cache_key $scheme$host$request_uri$request_method;
            #fastcgi_cache_valid 200 301 302 10m;
            #fastcgi_cache_use_stale updating error timeout invalid_header http_500;
            #fastcgi_pass_header Set-Cookie;
            #fastcgi_pass_header Cookie;
            #fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

            fastcgi_param SCRIPT_FILENAME $document_root/framework/main.php;
            fastcgi_param SCRIPT_NAME /framework/main.php;
            fastcgi_param QUERY_STRING url=$uri&$args;

            fastcgi_buffer_size 32k;
            fastcgi_buffers 4 32k;
            fastcgi_busy_buffers_size 64k;
    }

}

Это pool.d / www.conf details

pm = dynamic
pm.max_children = 30
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4
pm.max_requests = 500

В PHP установлено 128 МБ памяти, однако каждый процесс обычно составляет около 70 МБ.

Мне не удалось получить верхняя пока было 100 пользователей, но это обычное состояние:

             total       used       free     shared    buffers     cached
Mem:          3951       3793        157        114        273       2918
-/+ buffers/cache:        602       3348
Swap:            0          0          0

Вы увидите, что я экспериментировал с fastcgi_cache nginx, который сделал огромный разница в производительности (время загрузки 50 - 100 мс), однако на сайте есть много пользовательских функций (загрузка, изменение и т. д.), которые не работали, когда он был включен.

Я хотел бы еще раз взглянуть на fastcgi_cache, но я чувствую, что мы должны иметь возможность получить лучший результат на этом текущем сервере без него ?!

Некоторое время боролся с этим, так что любая помощь будет отличной.

Вы настроили pm.max_children до 30, что означает, что одновременно может выполняться не более 30 одновременных сценариев PHP.

Когда все больше пользователей посещают ваши сайты, отсутствуют какие-либо бесплатные процессы PHP для обслуживания запроса. nginx ждет некоторое время, прежде чем вернуть 504 Gateway Time-out ошибка.

Похоже, у вас много свободной памяти, так как ваш cached В столбце указано 2,9 ГБ свободной памяти.

Вы должны проверить среднее использование памяти вашими процессами PHP с помощью top команда. Нас интересует использование памяти RES столбец. Разделите 2 ГБ на это число, и вы получите безопасное число для pm.max_children настройка.

Вам также следует подумать о повышении стоимости pm.start_servers, pm.min_spare_servers и pm.max_spare_servers.

Резервные серверы - это процессы, которые доступны для немедленного обслуживания запросов. В противном случае менеджеру процессов PHP потребуется запустить процесс отдельно, что займет некоторое время.