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

Оптимизация apache для более 10 тысяч просмотров WordPress в день на процессоре E6500 с 2 ГБ оперативной памяти

У меня есть выделенный сервер с apache / php на ubuntu, обслуживающий мой блог Wordpress с примерно 10 тысячами просмотров страниц в день. У меня установлен плагин W3TC с APC.

Но время от времени сервер перестает отвечать или медленно работает, и мне приходится перезапускать apache, чтобы вернуть его.

Вот моя конфигурация, что я делаю не так?

ServerRoot "/etc/apache2"
LockFile /var/lock/apache2/accept.lock
PidFile ${APACHE_PID_FILE}
TimeOut 40
KeepAlive on
MaxKeepAliveRequests 200
KeepAliveTimeout 2
<IfModule mpm_prefork_module>
  StartServers 5
  MinSpareServers 5
  MaxSpareServers 8
  ServerLimit        80
  MaxClients         80
  MaxRequestsPerChild 1000
</IfModule>
<IfModule mpm_worker_module>
  StartServers       3
  MinSpareServers    3
  MaxSpareServers    3
  ServerLimit        80
  MaxClients         80
  MaxRequestsPerChild  1000
</IfModule>
<IfModule mpm_event_module>
  StartServers       3
  MinSpareServers    3
  MaxSpareServers    3
  ServerLimit        80
  MaxClients         80
  MaxRequestsPerChild  1000
</IfModule>
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
AccessFileName .htaccess
<Files ~ "^\.ht">
  Order allow,deny
  Deny from all
  Satisfy all
</Files>
DefaultType text/plain
HostnameLookups Off
ErrorLog /var/log/apache2/error.log
LogLevel error
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/httpd.conf
Include /etc/apache2/ports.conf
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog /var/log/apache2/other_vhosts_access.log vhost_combined
Include /etc/apache2/conf.d/
Include /etc/apache2/sites-enabled/

Мой стек производительности и кеширования WordPress

Это отличный стек производительности WordPress для одиночного сервера низкого и среднего уровня или VPS. Я классифицирую средний диапазон как одноядерный с около 1 ГБ памяти и довольно быстрыми дисками.

В вашем ящике это могло бы обслуживать более 10 тысяч просмотров страниц в час.

Серверный стек

  • Linux - либо Debian Lenny, либо Ubuntu
  • Nginx - настроен как статический файловый кеш обратного прокси
  • Apache - Apache будет обрабатывать PHP, выгруженный Nginx, на альтернативный порт.
  • MySql - требуется WP, убедитесь, что у вас установлена ​​последняя стабильная версия.
  • PHP - последняя стабильная версия 5.2 или ветка 5.3

Кэш PHP

  • APC - настройте его с памятью mmap и размером shm не менее 128M

Стек плагинов производительности WordPress

  • Интегратор кеширования прокси-сервера Nginx
  • W3 Общий кэш - Настройте кеш страницы на улучшенный диск, минимизируйте на диск, а объект и базу данных - на APC.
  • Self Hosted CDN - Создайте 4 псевдонима cname, которые указывают на домен на сервере, настроенном только для обслуживания статического файла

С W3 Total Cache мы используем диск для кеширования страниц и минимизируем, потому что Nginx будет обслуживать наши статические файлы очень быстро.

Как настроить Nginx для обслуживания статических файлов и передачи PHP в Apache

Проблема с использованием только Apache заключается в том, что он открывает соединение и запускает php при каждом запросе, даже для статических файлов. Это тратит впустую соединения, потому что Apache будет держать их открытыми, и когда у вас много трафика, ваши соединения будут зависать, даже если они не используются.

По умолчанию Apache прослушивает запросы через порт 80, который является веб-портом по умолчанию. Сначала мы собираемся внести изменения в наши файлы конфигурации Apache и виртуальных хостов для прослушивания порта 8080.

Конфигурация Apache

httpd.conf

отключите KeepAlive

ports.conf

NameVirtualHost *:8080
Listen 8080

Виртуальный хост для каждого сайта

<VirtualHost 127.0.0.1:8080>
     ServerAdmin info@yoursite.com
     ServerName yoursite.com
     ServerAlias www.yoursite.com
     DocumentRoot /srv/www/yoursite.com/public_html/
     ErrorLog /srv/www/yoursite.com/logs/error.log
     CustomLog /srv/www/yoursite.com/logs/access.log combined
</VirtualHost>

Вам также следует установить mod_rpaf поэтому ваши журналы будут содержать реальные IP-адреса ваших посетителей. Если нет, в ваших журналах будет 127.0.0.1 в качестве исходного IP-адреса.

Конфигурация Nginx

В Debian вы можете использовать репозитории для установки, но они содержат только версию 0.6.33. Чтобы установить более позднюю версию, вам необходимо добавить пакеты lenny backports

$ nano /etc/apt/sources.list

Добавьте эту строку в файл deb http://www.backports.org/debian lenny-backports main

$ nano /etc/apt/preferences

Добавьте в файл следующее:

Package: nginx
Pin: release a=lenny-backports 
Pin-Priority: 999

Выполните следующие команды, чтобы импортировать ключ с backports.org для проверки пакетов и обновления базы данных пакетов вашей системы:

$ wget -O - http://backports.org/debian/archive.key | apt-key add -
$ apt-get update

Теперь установите с помощью apt-get

apt-get install nginx

Это намного проще, чем компилировать из исходников.

Конфигурация Nginx и конфигурация файлов сервера

nginx.conf

user www-data;
worker_processes  4;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

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

    access_log  /var/log/nginx/access.log;
    client_body_temp_path /var/lib/nginx/body 1 2;
    gzip_buffers 32 8k;
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;

  gzip_comp_level   6;
  gzip_http_version 1.0;
  gzip_min_length   0;
  gzip_types        text/html text/css image/x-icon
        application/x-javascript application/javascript text/javascript application/atom+xml application/xml ;



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

Теперь вам нужно настроить виртуальный хостинг Nginx. Мне нравится использовать метод sites-enabled, когда каждый символ v host связан с файлом в каталоге sites-available.

$ mkdir /etc/nginx/sites-available  
$ mkdir /etc/nginx/sites-enabled
$ touch /etc/nginx/sites-available/yourservername.conf
$ touch /etc/nginx/sites-available/default.conf
$ ln -s  /etc/nginx/sites-available /etc/nginx/sites-enabled
$ nano /etc/nginx/sites-enabled/default.conf

default.conf

Примечание:

Настройки статического кеша в следующих файлах будут работать, только если включен плагин интегратора кеширования прокси Nginx.

proxy_cache_path  /var/lib/nginx/cache  levels=1:2   keys_zone=staticfilecache:180m  max_size=500m;
proxy_temp_path /var/lib/nginx/proxy;
proxy_connect_timeout 30;
proxy_read_timeout 120;
proxy_send_timeout 120;

#IMPORTANT - this sets the basic cache key that's used in the static file cache.
proxy_cache_key "$scheme://$host$request_uri";

upstream wordpressapache {
        #The upstream apache server. You can have many of these and weight them accordingly,
        #allowing nginx to function as a caching load balancer 
        server 127.0.0.1:8080 weight=1 fail_timeout=120s;
}

Конфигурация сайта WordPress (Для мультисайта вам понадобится только один vhost)

server {
        #Only cache 200 responses, and for a default of 20 minutes.
        proxy_cache_valid 200 20m;

        #Listen to your public IP
        listen 80;

        #Probably not needed, as the proxy will pass back the host in "proxy_set_header"
        server_name www.yoursite.com yoursite.com;
        access_log /var/log/nginx/yoursite.proxied.log;  

        # "combined" matches apache's concept of "combined". Neat.
        access_log  /var/log/apache2/nginx-access.log combined;
        # Set the real IP.
        proxy_set_header X-Real-IP  $remote_addr;

        # Set the hostname
        proxy_set_header Host $host;

        #Set the forwarded-for header.
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
                        # If logged in, don't cache.
                        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                                set $do_not_cache 1;
                        }
                        proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
                        proxy_cache staticfilecache;
                        proxy_pass http://wordpressapache;
        }

        location ~* wp\-.*\.php|wp\-admin {
                        # Don't static file cache admin-looking things.
                        proxy_pass http://wordpressapache;
        }

        location ~* \.(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
                        # Cache static-looking files for 120 minutes, setting a 10 day expiry time in the HTTP header,
                        # whether logged in or not (may be too heavy-handed).
                        proxy_cache_valid 200 120m;
                        expires 864000;
                        proxy_pass http://wordpressapache;
                        proxy_cache staticfilecache;
        }

        location ~* \/[^\/]+\/(feed|\.xml)\/? {
 # Cache RSS looking feeds for 45 minutes unless logged in.
                        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                                set $do_not_cache 1;
                        }
                        proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
                        proxy_cache_valid 200 45m;
                        proxy_cache staticfilecache;
                        proxy_pass http://wordpressapache;
        }

        location = /50x.html {
                root   /var/www/nginx-default;
        }

        # No access to .htaccess files.
        location ~ /\.ht {
                deny  all;
        }

        }

Конфигурация автономной CDN

Для вашей собственной CDN conf вам нужно только настроить его для обслуживания статических файлов без прокси-прокси.

server {

        proxy_cache_valid 200 20m;
        listen 80;
        server_name yourcdndomain.com;
        access_log   /srv/www/yourcdndomain.com/logs/access.log;
        root   /srv/www/yourcdndomain.com/public_html/;

 proxy_set_header X-Real-IP  $remote_addr;

      location ~* \.(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
                                # Cache static-looking files for 120 minutes, setting a 10 day expiry time in the HTTP header,
                                # whether logged in or not (may be too heavy-handed).

                                proxy_cache_valid 200 120m;
                        expires 7776000;
                        proxy_cache staticfilecache;
                }

location = /50x.html {
                root   /var/www/nginx-default;
        }

 # No access to .htaccess files.
        location ~ /\.ht {
          deny  all;
        }

    }

Теперь запустим серверы

$ /etc/init.d/apache2 restart  
$/etc/init.d/nginx start

Результаты тестов

На Apache Bench эта установка теоретически может обслуживать 1833,56 запросов в секунду.

$ ab -n 1000 -c 20 http://yoursite.com/

С помощью mod_status это способ увидеть, что происходит внутри нескольких экземпляров Apache, но учтите, что это действительно ухудшит производительность. Кажется, что он съедает память, и в одном случае мне не удалось диагностировать, было ли это причиной зависания одного процесса в настройке только обратного прокси, когда ничего не обслуживалось напрямую. Конечно, пользователи сообщают об этом, что «загрузка страницы занимает вечность». Они даже не понимают разницы между «нужно было подождать еще 10 секунд» и «это никогда не закончится», поскольку они обычно нажимают «Стоп» в своем браузере через несколько (<10) секунд.

Также проверьте, правильно ли вы настраиваете место (это легко увидеть с помощью mod_status, поскольку вы видите количество экземпляров / процессов). Стандартная конфигурация, по крайней мере, в ubuntu, имеет разделы ifdef для каждого режима MPM, и рабочий режим легко редактировать, когда вы запускаете prefork (как предполагает общепринятая мудрость из-за нечеткого ощущения, что PHP не является потокобезопасным).

О, и больше всего: беги наверху как root и следите за исчерпанными ресурсами. Память, диск, процессор - сами увидите.

Еще одно: идея деактивировать mod_deflate может быть хорошей, хотя ваши настройки не подвержены ошибкам из-за неправильной информации Content-Length, заставляющей браузер ждать данных «вечно», давая вам отчеты о «очень медленно» или «не отвечает».

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

Также включите Статус сервера модуль и посетите его, чтобы узнать, что происходит.

Возможно, вы меняете местами. Вы проверяли vmstat, пока это происходит? 2 ГБ ОЗУ для 80 MaxClients - это всего 25 МБ для каждого (при условии, что коробка больше ничего не делает). Возможно, ваши MaxClients слишком велики. Решение для этого очевидно: добавьте больше ОЗУ или уменьшите количество MaxClients. Если командная строка медленно реагирует при перезапуске apache, это одно из свидетельств данной ситуации.

Также возможно, что вы кормите некоторые мобильные клиенты (или другие клиенты с медленным подключением) «большими» файлами с ложечки, тем самым используя все ваши доступные слоты apache. Возможно, у вас слишком мало MaxClients. Проверка состояния сервера расскажет вам, что каждый из этих клиентов делает в это время. Одно из решений для этой ситуации - увеличить MaxClients (но это также может превратиться в ситуацию, описанную выше). Лучшее решение для этого - установить ускоритель HTTP перед apache (один бесплатный вариант - perlbal.) Если ваша командная строка нормальная скорость при перезапуске apache, это одно из указаний на эту ситуацию.

Это похоже на стандартную конфигурацию Apache, хотя кажется, что часть ее была удалена из-за того, что она похожа на HTML.

Вам нужно выяснить, что происходит, когда ваш сервер медленно реагирует. Вы не говорите о характеристиках своего сервера, но упоминаете, что он выделен и 10 КБ в день должны быть легко обработаны.

  • Что показывает топ?
  • Где узкое место? ЦП, память, ввод-вывод Подождите?
  • Сколько процессов Apache запущено?
  • Сколько подключений отображается в netstat?

Предполагается, что ЦП - это узкое место, вызванное PHP. Использование APC и плагина кэширования WP - хорошие способы облегчить это, что вы уже сделали. Вы также можете попробовать модель процесса «MPM» Apache вместо «Prefork». Убедитесь, что для APC выделено достаточно памяти, чтобы он мог кэшировать ваши PHP-скрипты и не «пропустить».

Это также может быть MySQL - посмотрите, не перегружает ли это процессор или диск.

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

Используйте такие инструменты, как 'siege' или 'ab', чтобы протестировать ваш сервер и выяснить, в какой момент ваш сервер замедляется.

Вот некоторые из моих закладок по настройке производительности веб-сервера: http://articles.slicehost.com/2010/5/19/configuring-the-apache-mpm-on-ubuntu

http://www.thebuzzmedia.com/increase-wordpress-performance-on-apache-with-worker-mpm-php-and-mod_fcgid/

http://www.devside.net/articles/apache-performance-tuning

http://www.brandonturner.net/blog/2009/07/fastcgi_with_php_opcode_cache/

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

Некоторые советы, особенно если вы размещаете много медиафайлов:

  • Переместите свои медиафайлы в выделенный экземпляр Apache (или лучше: nginx). Никакого PHP, никаких модулей, только чистый http-сервер, который будет доставлять медиафайлы как можно быстрее.
  • Кеш, кеш, кеш! Используйте плагин super cache для wordpress. Это очень помогает.
  • Проверьте свою конфигурацию apache по заголовкам. Убедитесь, что у изображений и других «стабильных» носителей время истечения срока действия установлено на отдаленную дату, и что ваш apache возвращает код HTTP 304 по запросу клиентов.
  • Включите mod_deflate. Это может снизить производительность, поскольку клиенты будут быстрее обслуживаться.