Озадачившиь необходимостью повышения быстродействия сайта на Drupal 6, пришлось перерыть множество ресурсов в поисках рекомендаций. Данная cms помимо больших возможностей и гибкости конфигурирования отличается еще и высокими требованиями к ресурсам - активно использует множество запросов к базе данных, имеет достаточно тяжелые скрипты. Что, впрочем, не мешает ее применению на высокопосещаемых ресурсах. Однако каких-либо впечатляющих результатов быстродействия невозможно достичь без комплексной и детальной настройки.
Нижеприведенные рецепты во многом применимы и для Drupal 7.
Если с чего и стоит начать так это с настройки базы данных. Без этого все другие методы повышения быстродействия не имеют смысла. Все дело в том, что настройки Mysql по умолчанию позволяют ей начать работать на любом обрудовании. Однако о каком-либо приемлемом уровне производительности в таком виде речь не идет. Это связано с тем, что настройки сильно связаны как с вычислительными мощностями оборудования (процессор, количество памяти), так и с типом хранимых данных. Поэтому и не существует универсального рецепта настройки.
В Интернете много статей по тюнингу Mysql. Чтобы в очередной раз не капать из пипетки в океан, приведу ссылку на наиболее грамотное и конкретное, по моему мнению, howto: MySQL-тюнинг. Настраиваем по-взрослому. От себя только добавлю, что рекомендации датированы 2008 годом и в новых версиях названия некоторых опций могут отличаться.
Проконтроллировать результат и точнее подобрать параметры поможет скрипт mysqltuner.pl.
Обычный вариант установки Drupal подразумевает использование веб-сервера Apache. В этом случае гарантируется максимальное использование возможностей cms и удобства настройки. Модель рабочего процесса для Apache по умолчанию apache-prefork. Это достаточно стабильная модель работы сервера, но не использующая механизм потоков (threads).
С целью улучшения производительности нередко рекомендуют вместо apache-prefork использовать apache-worker - мультипроцессорно-мультипоточную модель. Однако в этом случае теряется возможность обработки php с помощью модуля apache (mod_php), который не поддерживает работу с worker-моделью. Выполнение скриптов возможно в режиме cgi, fastcgi и т.п.
В моем случае разницы во времени генерации одиночной страницы практически не было. Очевидно, что apache-worker будет иметь преимущество только при множестве одновременных запросах.
Другой часто рекомендуемый метод оптимизации - установка веб-сервера nginx в качестве фронтэнда к Apache. При этом статические запросы обрабатывает nginx, а выполнение скриптов поручается делать Apache. Такая связка призвана разгрузить Apache от работы со статикой, улучшив тем самым производительность.
Сочетание apache+nginx часто используется для проектов с высокой посещаемостью. Естественно возникло желание попробовать nginx. И тут возник вопрос: если обработкой статики будет заниматься nginx, php будет исполняться как fastcgi, то что в таком случае остается Apache? Неужели только ради удобства с .htaccess и привычного mod_rewrite следует запускать такой навороченный сервер? Поэтому было принято решение использовать nginx в качестве единственного веб-сервера.
Поскольку в качестве web-сервера выбор пал на nginx, то обработка php-скриптов будет осуществляться в режиме fastcgi. Запуском и управлением процессами php занимается FPM (FastCGI Process Manager), доступный с версии php-5.3.3 (и в виде патча в более ранних).
Примерный конфиг выглядит следующим образом:
;; /etc/php5/fpm/php-fpm.conf [global] pid = /var/run/php-fpm.pid error_log = /var/log/php-fpm.log syslog.facility = daemon syslog.ident = php-fpm log_level = warning process.max = 128 process.priority = -10 events.mechanism = epoll [www] user = wwwrun group = www listen = 127.0.0.1:9000 listen.owner = wwwrun listen.group = www listen.mode = 0666 listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 500 slowlog = /var/log/$pool.log.slow env[HOSTNAME] = $HOSTNAME env[PATH] = /usr/local/bin:/usr/bin:/bin env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp ;; здесь можно задать параметры php для каждого пула аналогично php.ini php_flag[display_errors] = off php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 512M php_admin_value[date.timezone] = 'Europe/Moscow' php_admin_value[upload_max_filesize] = 16M php_admin_value[post_max_size] = 16M php_admin_value[cgi.fix_pathinfo] = 0 php_admin_value[expose_php] = off php_admin_value[magic_quotes_gpc] = 0 php_admin_value[max_execution_time] = 60 php_admin_value[max_input_time] = 120 php_admin_value[allow_url_fopen] = off
На самом деле опций в php-fpm.conf намного больше. Выше приведены только те, что отличаются от умолчальных.
Пример настройки Nginx для работы с Drupal 6. Поскольку сайтов может быть несколько, стандартный конфиг /etc/nginx/nginx.conf удобно разбить на части, включая нужные при необходимости. Так в моем примере nginx.conf содержит общие настройки и сервер по умолчанию, common.conf - часто повторяющиеся настройки для каждого сайта, файл access.conf содержит белый список адресов при ограниченном доступе, drupal.conf - специальные настройки именно для друпала. И в конфиге виртуального хоста vhosts.d/site_name.tld.conf все это собирается воедино.
############### /etc/nginx/nginx.conf ############### worker_processes 3; worker_priority -10; error_log /var/log/nginx/error.log crit; timer_resolution 100ms; worker_rlimit_nofile 8192; events { worker_connections 4000; use epoll; multi_accept on; } http { include mime.types; default_type application/octet-stream; access_log off; open_file_cache max=10000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; sendfile on; directio 128k; directio_alignment 4K; # for XFS filesystem output_buffers 1 512k; tcp_nopush on; keepalive_timeout 30; keepalive_requests 100000; reset_timedout_connection on; client_max_body_size 16M; client_body_timeout 10; send_timeout 2; access_log off; gzip_static on; gzip on; gzip_min_length 1100; gzip_buffers 64 8k; gzip_comp_level 3; gzip_http_version 1.1; gzip_proxied any; gzip_types text/plain application/xml application/x-javascript text/css; gzip_disable "MSIE [1-6]\."; gzip_vary on; server { listen 80; server_name localhost; charset utf-8; access_log off; location / { root /srv/www/htdocs/; index index.html index.htm; } error_page500 502 503 504 /50x.html; location = /50x.html { root /srv/www/htdocs/; } } include vhosts.d/*.conf; }
############### /etc/nginx/common.conf ############### ## убираем www из имени сайта if ($host ~* www\.(.*)) { set $host_without_www $1; rewrite ^(.*)$ http://$host_without_www$1 permanent; } ## разрешаем только необходимые методы if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } ## можно запретить доступ ботам-реферальщикам if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { return 403; } ## Запретим доступ к файлам начинающимся с точки location ~ (^|/)\. { return 403; } location = /favicon.ico { log_not_found off; access_log off; } ## Запретим доступ к логам и текстовым файлам с адресов вне белого списка location ~* \.(txt|log)$ { include access.conf; } location = /robots.txt { allow all; log_not_found off; access_log off; } ## Запретим доступ к php-файлам выше корневого каталога сервера location ~ \..*/.*\.php$ { return 403; }
############### /etc/nginx/access.conf ############### ## т.н. белый список адресов allow 192.168.0.1/24; allow 127.0.0.1/32; deny all;
############### /etc/nginx/drupal.conf ############### ## Чистые ссылки для друпал location / { try_files $uri @rewrite; default_type text/html; log_not_found off; } location @rewrite { # You have 2 options here # For D7 and above: # Clean URLs are handled in drupal_environment_initialize(). #rewrite ^ /index.php; # For Drupal 6 and bwlow: # Some modules enforce no slash (/) at the end of the URL # Else this rewrite block wouldn't be needed (GlobalRedirect) rewrite ^/(.*)$ /index.php?q=$1; # Drupal in a subdirectory #rewrite ^/([^/]*)/(.*)(/?)$ /$1/index.php?q=$2&$args; } ## Ограничиваем доступ к cron.php location = /cron.php { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; include access.conf; } ## Обрабатываем php-скрипты через php-fpm location ~ \.php$ { include fastcgi_params; fastcgi_split_path_info ^(.+\.php)(/.+)$; #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini fastcgi_intercept_errors on; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; } ## Требуется для работы imagecache # This is for Drupal 6 location ~ ^/sites/.*/files/imagecache/ { # This is for Drupal 7 and 8 #location ~ ^/sites/.*/files/styles/ { try_files $uri @rewrite; expires 1y; } ## Позволяем использовать кэш браузера клиента для статичных файлов location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 1y; log_not_found off; if_modified_since before; access_log off; }
############### /etc/nginx/vhosts.d/site_name.tld.conf ############### server { ## можно перечислить через пробел все имена сайта, аналогично алиасам в апаче server_name site_name.tld; include common.conf; ## Путь к каталогу друпала root /home/web_user/drupal; listen 80; charset utf-8; ## Путь к логу доступа access_log /home/web_user/log/site_name.tld-access.log; error_page 404 /404.html; error_page 403 /403.html; include drupal.conf; }
Подробное описание всех опций см. на официальном сайте и вики.
Чтобы не выполнять одно и тоже существуют кэши.
1. Результат интерпретации php-скриптов - кэш операционного кода.
2. Результаты выдачи БД - кэш запросов.
В качестве первого обычно используют php-акселераторы.
В Drupal имеется стандартный кэш запросов, настраиваемый в admin/settings/performance. Однако эффективность его работы не лишена нареканий. Поэтому в качестве меры по повышению быстродействия рекомендуется сменить стандартное кэширование на что-то более эффективное.
Поиск простых и лаконичных решений привел к xcache. Дело в том, что xcache умеет кэшировать не только операционный код скриптов, но и запросы. Тем самым решаются сразу две задачи.
Устанавливается xcache как расширение PHP, примерная конфигурация выглядит следующим образом:
;; /etc/php5/conf.d/xcache.ini [xcache-common] extension = xcache.so [xcache] xcache.shm_scheme = "mmap" xcache.size = 192M xcache.count = 4 xcache.slots = 8K xcache.ttl = 36000 xcache.gc_interval = 3600 xcache.var_size = 24M xcache.var_count = 2 xcache.var_slots = 8K xcache.var_ttl = 36000 xcache.var_maxttl = 604800 xcache.var_gc_interval = 300 xcache.var_namespace_mode = 0 xcache.var_namespace = "" xcache.readonly_protection = Off xcache.mmap_path = "/var/tmp/xcache" xcache.disable_on_crash = Off xcache.experimental = Off xcache.cacher = On xcache.stat = On xcache.optimizer = On [xcache.coverager] xcache.coverager = Off
xcache.size - размер кэшей опкода,
xcache.count - количество кэшей (по числу ядер процессора),
xcache.ttl - время жизни данных, если к ним не обращались (секунд),
xcache.gc_interval - интервал сборки мусора (секунд);
xcache.var_size - размер кэшей запросов и т.д.
Для применения настроек перезапускаем php-fpm.
Чтобы drupal вместо стандартного кэша запросов использовал возможности xcache, используется модуль cacherouter. Включаем его на странице модулей admin/build/modules, в файл настроек сайта sites/sitename.tld/settings.php добавляем следующее:
Другие необходимые действия, которые обязательно следует предпринять:
- агрегация css и js-скриптов;
- сжатие контента gzip средствами сервера, а не cms;
- оптимизация размера изображений;
- периодическая дефрагментация таблиц базы данных;
- чистка базы от мусора, часто бывает в таблицах blocks и variable как результат неполного или некорректного удаления модулей и тем.
В качестве дополнительных улучшений можно посоветовать следующее:
1) модуль locale_static позволяет сделать локализацию в виде сериализованного массива данных, который еще и прекрасно кэшируется.
2) вместо стандартного поиска можно использовать более производительный движок sphinx, используемый модуль advanced_sphinx.
приветствую! Есть вопросец :)
Я вот тоже установил xcache, и все бы ок, но есть одна проблема!
Работает сервер с Апачем с mod-fcgid, и вопреки настройкам кешера, кеш сбрасывается примерно каждые два часа, (насколько я понимаю, это происходит потому, что fcgi имеет свойство периодически убивать процессы)… И это очень пичально :(
Решается ли как-то этот вопрос с использованием php-FPM, или какими-то другими способами?
- Войдите на сайт для отправки комментариев
- cсылка
⏏Можно попробовать поиграться со временем жизни кэша в настройках xcache.
- Войдите на сайт для отправки комментариев
- cсылка
⏏