Переезд XenForo форума на современную платформу

—

от автора

Зачем это было нужно

Площадка для сообщества нашего продукта давно работает на базе форумного движка 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *