Зачем это было нужно
Площадка для сообщества нашего продукта давно работает на базе форумного движка XenForo. До недавнего времени, форум работал VPS на базе CentOS 6.8 с вендорским Apache 2.2.15, MySQL 5.1 и PHP 5.6.
В связи с приближающимся релизом XenForo 2.0, у которого повышенные требования к компонентам, и общим желанием ускорить работу форума на современной компонентной базе, было принято решение о переезде на VPS с nginx, последней версией PHP и базой данных, работающей на Percona Server 5.7.
Приведенная ниже инструкция не претендует на идеальное решение с идеальной конфигурацией и может рассматриваться как общий план использования XenForo на nginx хостинге. Инструкция в первую очередь предназначена для тех администраторов XenForo, которые не слишком сильны в тонкостях администрирования Linux и хотели бы иметь какую-то общую базовую инструкцию.
Подготовка VPS
В качестве операционной системы была выбрана CentOS 7.3 просто потому, что администратору rpm-based OSes ближе, чем deb-based 🙂
VPS располагает 25Gb дискового пространства, 4Gb RAM, а команда
# cat /proc/cpuinfo | grep processor | wc -l
показывает число 8.
Сначала удаляем все ненужные пакеты, такие как Samba, httpd, и все, что посчитаете ненужным. Затем устанавливаем все доступные апдейты из официального репозитория с помощью:
# yum update
Далее нужно подключить все необходимые third-party репозитории и установить нужные нам компоненты. Первым устанавливаем сервер баз данных Percona. Подключаем репозиторий и устанавливаем необходимые пакеты:
# yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm # yum install Percona-Server-server-57
Здесь тонкость в том, что во время установки генерируется временный админский пароль, который нужно найти с помощью команды:
# grep 'temporary password' /var/log/mysqld.log
Он нам потребуется для дальнейшей security настройки Percona Server командой:
# /usr/bin/mysql_secure_installation
После этого вы получите постоянный пароль для вашего сервера баз данных.
Далее устанавливаем репозиторий nginx и сам пакет nginx:
# yum install epel-release # yum install nginx
После этого устанавливаем свежайшую версию PHP со всеми необходимыми компонентами:
# cd /tmp # curl 'https://setup.ius.io/' -o setup-ius.sh # bash setup-ius.sh # yum install php71u-fpm-nginx php71u-cli php71u-mysqlnd php71u-pecl-memcached php71u-opcache php71u-gd memcached
Включаем все нужные сервисы с помощью
# systemctl enable nginx # systemctl enable memcached # systemctl enable mysql # systemctl enable php-fpm
чтобы после перезагрузки сервера, все они запускались автоматически.
На этом подготовку заканчиваем и приступаем к самому сложному, настройке всего этого хозяйства для оптимальной работы нашего XenForo форума.
Настройка сервисов
В этом разделе не следует принимать все, как истину в последней инстанции. Опытные администраторы могут указать гораздо более лучшие тонкие настройки. Неопытным предлагается некие общие рекомендации, которые они могут использовать один в один, как реально работающую конфигурацию, либо использовать их, как шаблон для собственной индивидуальной конфигурации.
Итак, для начала в файле /etc/php.ini установим значение параметра cgi.fix_pathinfo=0. Затем идем в файл /etc/php-fpm.d/www.conf, комментируем строчку listen = 127.0.0.1:9000 и раскомментируем listen = /run/php-fpm/www.sock. Дополнительно включаем listen.acl_users = nginx. Должно быть что-то вроде:
;listen = 127.0.0.1:9000 listen = /run/php-fpm/www.sock listen.acl_users = nginx
В файле /etc/nginx/conf.d/php-fpm.conf тоже включаем работу через сокет:
#server 127.0.0.1:9000; server unix:/run/php-fpm/www.sock;
Перезапускаем php-fpm:
# systemctl retsart php-fpm
Сервис memcached используем по умолчанию. Запускаем его с помощью:
# systemctl start memcached
убеждаемся, что порт 11211 открылся для соединений и настраиваем в конфиге XenForo его использование для кэширования backend-а в соответствии с официальной документацией XenForo. Но тут есть тонкость, вместо строчки
$config['cache']['backend'] = 'Memcached';
у меня заработала строчка
$config['cache']['backend']='Libmemcached';
Percona Server можно попробовать оптимизировать с помощью их визарда, либо известным скриптом mysqltuner.pl Все на ваше усмотрение и в соответствии с ресурсами вашего железа.
Имейте только в виду, что конфигурационный файл находится в /etc/percona-server.conf.d/mysqld.cnf
Самая сложная часть в этой истории — конфигурация nginx. В основных настройках ничего особенного. Только правильно выставите значения worker_processes (количество процессоров определяется командой cat /proc/cpuinfo | grep processor | wc -l) и worker_connections (worker_processes * 1024):
user nginx; worker_processes 8; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 8192; use epoll; multi_accept on; }
Дальше идет блок httpd. Тут тоже особенных тонкостей нет, за исключением одной, весьма важной. Дело в том, что у нас используется кэширование FastCGI, и для этого потребуются дополнительные настройки. Это кэширование требует включения двух блоков конфигурации в разных блоках nginx.conf. Для начала, как все выглядит в блоке httpd:
http { access_log off; server_tokens off; charset utf-8; reset_timedout_connection on; send_timeout 15; client_max_body_size 10m; client_header_buffer_size 1k; client_header_timeout 15; client_body_timeout 30; large_client_header_buffers 4 4k; open_file_cache max=1000 inactive=20s; open_file_cache_min_uses 5; open_file_cache_valid 30s; open_file_cache_errors off; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; keepalive_requests 100000; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ### FastCGI Cache ################ map $http_cookie $nocachecookie { default 0; ~xf_fbUid 1; ~xf_user 1; ~xf_logged_in 1; } map $request_uri $nocacheuri { default 0; ~^/register 1; ~^/login 1; ~^/validate-field 1; ~^/captcha 1; ~^/lost-password 1; ~^/two-step 1; } fastcgi_cache_path /tmp/nginx_fastcgi_cache levels=1:2 keys_zone=fastcgicache:200m inactive=30m; fastcgi_cache_key $scheme$request_method$host$request_uri; fastcgi_cache_lock on; fastcgi_cache_use_stale error timeout invalid_header updating http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; ### FastCGI Cache ################
Дальше мы еще вернемся к особенностям включения FastCGI кэширования в другом блоке, а пока посмотрим на следующий блок, server:
server { listen 80 reuseport; listen 443 ssl reuseport http2; server_name domain.com; root /var/www/html; ssl_certificate "/etc/nginx/ssls/ssl-bundle.crt"; ssl_certificate_key "/etc/nginx/ssls/domain_com.key"; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; add_header Strict-Transport-Security max-age=15768000; location ~ /.well-known { allow all; } client_max_body_size 100m;
Здесь важно конфигурирование SSL сертификата. В нашем случае используется сертификат от Comodo. Инструкция по его подключению можно найти на их сайте, а для генерации /etc/ssl/certs/dhparam.pem используем команду:
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Последующую проверку правильности настройки SSL сертификата можно сделать тут.
И, наконец, последние важные блоки конфига nginx:
location / { index index.php index.html; try_files $uri $uri/ /index.php?$uri&$args; } location ~ /(internal_data|library) { internal; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } location ~ \.php$ { try_files $uri /index.php?$uri&$args; fastcgi_max_temp_file_size 1M; fastcgi_cache_use_stale updating; fastcgi_pass_header Set-Cookie; fastcgi_pass_header Cookie; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; include fastcgi_params; ### fastcgi_cache ### fastcgi_cache fastcgicache; fastcgi_cache_bypass $nocachecookie $nocacheuri; fastcgi_no_cache $nocachecookie $nocacheuri; fastcgi_cache_valid 200 202 302 404 403 5m; fastcgi_cache_valid 301 1h; fastcgi_cache_valid any 1m; add_header X-Cache $upstream_cache_status; ### fastcgi_cache end ### } gzip on; gzip_http_version 1.1; gzip_vary on; gzip_min_length 1100; gzip_buffers 64 8k; gzip_comp_level 6; gzip_proxied any; gzip_types image/png image/gif image/svg+xml image/jpeg image/jpg text/xml text/javascript text/plain text/css application/json application/javascript application/x-javascript application/vnd.ms-fontobject gzip_disable "MSIE [1-6]\.(?!.*SV1)"; location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ { expires 30d; add_header Pragma public; add_header Cache-Control "public"; } } }
Здесь очень важны параметры location для корректной работы ссылок ЧПУ, скриптов PHP и закрытия доступа к важным внутренним директориям internal_data и library. Кроме того, здесь включается gzip компрессия и кэширование статический медиа файлов. Ну и вторая часть настройки FastCGI кэширования.
Собственно сам переезд контента форума состоял в переносе дампа базы данных и tar.gz архива содержимого форумного root directory и разворачивании их на новом сервере.
Дополнительная информация о кэшировании в nginx
В начале, я попытался использовать nginx microcaching. Для начала создал директорию для хранения кэша:
# mkdir /var/cache/nginx2
Создал файл /etc/nginx/conf.d/microcache.conf с содержимым:
fastcgi_cache_path /var/cache/nginx2 levels=1:2 keys_zone=microcache:5m max_size=1000m; map $http_cookie $cache_uid { default nil; # hommage to Lisp ~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+) $session_id; } map $request_method $no_cache { default 1; HEAD 0; GET 0; }
и в конфиге nginx для php location сделал так:
location ~ \.php$ { fastcgi_cache microcache; fastcgi_cache_key $server_name|$request_uri; fastcgi_cache_valid 404 30m; fastcgi_cache_valid 200 10s;
В принципе, все заработало отлично, форум стал работать очень быстро, за исключением одной проблемы — стали странно работать сессии зарегистрированных и залогиненых пользователей. Внезапно вы обнаруживали, что вы разлогинены и нужно было логинится опять.
Оказалось, что проблема лежит в глубинах движка XenForo и решается установкой плагина Logged In Cookie и правкой темплейтов XenForo helper_login_form и login_bar_form заменой строки:
<label class="rememberPassword"><input type="checkbox" name="remember" value="1" id="ctrl_pageLogin_remember" tabindex="3" /> {xen:phrase stay_logged_in}</label>
на строку:
<input type="hidden" name="remember" checked="checked" value="1" />
Но все это я узнал позже, когда настроил описанное выше FastCGI кэширование, с которым теперь все работает отлично. Поэтому, я думаю, проблема с сессиями решилась бы и для nginx microcaching, но я не проверял. Вы можете попробовать этот вариант кэширования.
Вывод
После тестирования форума на Google Pagespeed и соответствующей дополнительной оптимизации, существенное ускорение работы форума было нельзя не заметить. Сейчас форум набирает 86 баллов из 100. Раньше, на Apache было 78 баллов. Есть еще над чем работать в плане оптимизации кода, в особенности для мобильной версии.
Мониторинг потребляемых ресурсов VPS при самой высокой нагрузке форума тоже позволяет судить об очень небольшом их потреблении. Интерфейс форума был недавно полностью переработан в соответствии с новым корпоративным стандартом, и в сочетании с реактивной отзывчивостью стал дополнительным плюсом для привлечения новых членов нашего сообщества.
P.S. Был бы очень признателен знатокам и экспертам nginx в указании на ошибки и советах по дополнительной оптимизации конфигурации.
ссылка на оригинал статьи https://habrahabr.ru/post/326636/
Добавить комментарий