Поиск по сайту:

Как разделить сеансы PHP на нескольких серверах Memcached в Ubuntu 14.04


Введение

Memcached — это распределенная система кэширования объектов, которая хранит информацию в памяти, а не на диске, для более быстрого доступа. Модуль PHP Memcache можно использовать для обработки сессий, которые в противном случае хранились бы в файловой системе. Хранение сессий PHP в Memcached имеет то преимущество, что их можно распределять по нескольким облачным серверам, на которых работает Memcached, чтобы поддерживать избыточность сессий.

Без этой настройки Memcached, если ваше приложение балансирует нагрузку на нескольких серверах, необходимо было бы настроить привязку сеанса к балансировщику нагрузки. Это поддерживает взаимодействие с пользователем и предотвращает его внезапный выход из системы. Настройка Memcached для обработки сеансов гарантирует, что все облачные серверы в пуле Memcached будут иметь одинаковый набор данных сеанса, что устраняет необходимость привязки к одному серверу для сохранения сеанса.

Предпосылки

В этом руководстве предполагается, что вы знакомы с настройкой серверов LAMP в Ubuntu.

Капля 1

  • Название: lamp01
  • Общедоступный IP-адрес: 1.1.1.1
  • Частный IP-адрес: 10.1.1.1

Капля 2

  • Название: lamp02
  • Общедоступный IP-адрес: 2.2.2.2
  • Частный IP-адрес: 10.2.2.2

Капля 3

  • Название: lamp03
  • Общедоступный IP-адрес: 3.3.3.3
  • Частный IP-адрес: 10.3.3.3

Убедитесь, что флажок «Частная сеть» установлен при создании капель. Также запишите частные IP-адреса, так как они понадобятся нам позже.

Установите LAMP на все три сервера.

Сначала обновите репозиторий и установите Apache.

apt-get update
apt-get install apache2

Установите PHP и расширение mod_php для Apache.

apt-get install php5 libapache2-mod-php5 php5-mcrypt

Дополнительные сведения см. в этой статье.

Шаг первый — установите пакеты Memcache

На lamp01 установите демон Memcached и модуль Memcache PHP.

apt-get install php5-memcache memcached

В PHP есть два пакета: php5-memcache и php5-memcached (обратите внимание на «d» в конце). Мы будем использовать первый пакет (memcache), так как он легче и не содержит каких-либо зависимостей. Прочтите сравнение между memcache и memcached.

Служба Memcached прослушивает только локальный хост (127.0.0.1). Это необходимо изменить, чтобы принимать подключения из частной сети.

nano /etc/memcached.conf

Найдите следующую строку:

-l 127.0.0.1

Измените его, чтобы прослушивать частный IP-адрес этого сервера.

-l 10.1.1.1

Перезапустите службу memcached.

service memcached restart

Повторите эти шаги на двух других серверах, заменив 127.0.0.1 соответствующим частным IP-адресом.

лампа02

-l 10.2.2.2

лампа03

-l 10.3.3.3

Перезапустите службу memcached на вторых двух серверах.

Шаг второй — установите Memcache в качестве обработчика сеанса PHP

На lamp01 откройте файл php.ini для редактирования.

nano /etc/php5/apache2/php.ini

Этот файл находится в /etc/php5/fpm/php.ini при установке PHP-FPM.

Найдите следующие директивы конфигурации:

session.save_handler =
session.save_path =

Измените их для использования Memcache следующим образом. Используйте все три частных IP-адреса в session.save_path.

session.save_handler = memcache
session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'

Возможно, вам придется раскомментировать session.save_path, удалив точку с запятой в начале. Не забудьте ввести номер порта 11211 после каждого IP-адреса, так как Memcached прослушивает этот порт.

Добавьте точно такие же настройки на двух других серверах.

На лампе02:

session.save_handler = memcache
session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'

На лампе03:

session.save_handler = memcache
session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'

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

Шаг третий — настроить Memcache для резервирования сеанса

На лампе 01 отредактируйте файл memcache.ini.

nano /etc/php5/mods-available/memcache.ini

Добавьте следующие директивы конфигурации в конец этого файла.

memcache.allow_failover=1
memcache.session_redundancy=4

Директива memcache.session_redundancy должна быть равна количеству серверов memcached + 1, чтобы информация о сеансе реплицировалась на все серверы. Это связано с ошибкой в PHP.

Эти директивы обеспечивают отработку отказа и избыточность сеанса, поэтому PHP записывает информацию о сеансе на все серверы, указанные в session.save_path; аналогично настройке RAID-1.

Перезапустите веб-сервер или демон PHP FPM в зависимости от того, что используется.

service apache2 reload

Точно повторите эти шаги для ламп 02 и 03.

Шаг четвертый — проверка избыточности сеанса

Чтобы протестировать эту настройку, создайте следующий PHP-скрипт на всех каплях.

/var/www/html/session.php

<?php
    header('Content-Type: text/plain');
    session_start();
    if(!isset($_SESSION['visit']))
    {
    	echo "This is the first time you're visiting this server\n";
    	$_SESSION['visit'] = 0;
    }
    else
            echo "Your number of visits: ".$_SESSION['visit'] . "\n";

    $_SESSION['visit']++;

	echo "Server IP: ".$_SERVER['SERVER_ADDR'] . "\n";
	echo "Client IP: ".$_SERVER['REMOTE_ADDR'] . "\n";
	print_r($_COOKIE);
?>

Этот сценарий предназначен только для тестирования и может быть удален после настройки капель.

Получите доступ к этому файлу в первой капле с помощью curl и извлеките информацию о файлах cookie.

curl -v -s http://1.1.1.1/session.php 2>&1 | grep 'Set-Cookie:'

Это вернет вывод, аналогичный следующему.

< Set-Cookie: PHPSESSID=8lebte2dnqegtp1q3v9pau08k4; path=/

Скопируйте файл cookie PHPSESSID и отправьте запрос другим каплям, используя этот файл cookie. Этот сеанс будет удален PHP, если в течение 1440 секунд не будет выполнено никаких запросов, поэтому убедитесь, что вы завершили тест в течение этого периода времени. Прочтите о PHP session.gc-maxlifetime, чтобы узнать больше об этом.

curl --cookie "PHPSESSID=8lebte2dnqegtp1q3v9pau08k4" http://1.1.1.1/session.php http://2.2.2.2/session.php http://3.3.3.3/session.php

Вы обнаружите, что сеанс переносится на все капли.

Your number of visits: 1
Server IP: 1.1.1.1
Client IP: 117.193.121.130
Array
(
    [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
)
Your number of visits: 2
Server IP: 2.2.2.2
Client IP: 117.193.121.130
Array
(
    [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
)
Your number of visits: 3
Server IP: 3.3.3.3
Client IP: 117.193.121.130
Array
(
    [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
)

Чтобы протестировать отказоустойчивость, остановите службу memcached и откройте на ней этот файл.

service memcached stop

Капля прозрачно использует информацию о сеансе, хранящуюся на двух других серверах.

curl --cookie "PHPSESSID=8lebte2dnqegtp1q3v9pau08k4" http://1.1.1.1/session.php

Выход:

Your number of visits: 4
Server IP: 1.1.1.1
Client IP: 117.193.121.130
Array
(
    [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
)

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

После завершения тестирования снова запустите memcached:

service memcached start

Шаг пятый — защитите Memcached с помощью IPTables

Даже если Memcached использует частную сеть, другие пользователи DigitalOcean в том же центре обработки данных могут подключиться к вашей капле, если они знают ваш частный IP-адрес. Итак, мы настроим правила IPTables, чтобы только облачные серверы в нашем пуле Memcached могли взаимодействовать друг с другом.

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

Создайте правила брандмауэра для lamp01 с частными IP-адресами lamp02 и lamp03.

iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT

На типичном сервере LAMP полный набор правил будет следующим:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
iptables -P INPUT DROP

Введите правила брандмауэра для lamp02 с частными IP-адресами lamp01 и lamp03.

iptables -A INPUT -s 10.1.1.1 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT

Сделайте то же самое на лампе 03 с частными IP-адресами ламп 01 и 02.

iptables -A INPUT -s 10.1.1.1 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT

Повторите тесты на шаге 4, чтобы убедиться, что брандмауэр не блокирует наш трафик.

Дополнительное чтение

  • Как установить стек LAMP в Ubuntu 14.04
  • Как изолировать серверы в частной сети с помощью IPTables
  • Как сохранить сеансы PHP в Memcached