Подтвердить что ты не робот

Сессии PHP в кластере балансировки нагрузки - как?

ОК, поэтому у меня есть совершенно редкий уникальный сценарий веб-сайта PHP с балансировкой нагрузки. Облом - это не было балансировкой нагрузки. Теперь мы начинаем получать проблемы...

В настоящее время единственная проблема связана с сеансами PHP. Естественно, никто не думал об этой проблеме сначала, поэтому конфигурация сеанса PHP осталась по умолчанию. Таким образом, у обоих серверов есть своя небольшая таблица файлов сеансов, а горе - пользователь, который получает следующий запрос, брошенный на другой сервер, потому что у него нет сеанса, который он создал на первом.

Теперь я читал руководство PHP о том, как решить эту ситуацию. Там я нашел хорошую функцию session_set_save_handler(). (И, по совпадению, этот раздел на SO). Кроме того, мне придется называть эту функцию на всех страницах веб-сайта. И разработчикам будущих страниц пришлось бы помнить, что все это время звонят. Чувствует себя неловко, не говоря уже о том, что, вероятно, нарушает десяток лучших методов кодирования. Было бы гораздо приятнее, если бы я мог просто перевернуть какую-то глобальную конфигурационную опцию, а Voilà - сеансы, которые все магически хранятся в БД или кеше памяти или что-то в этом роде.

Любые идеи о том, как это сделать?


Добавлено: Чтобы уточнить - я ожидаю, что это стандартная ситуация со стандартным решением. FYI. У меня есть MySQL DB. Наверняка должен быть какой-то готовый к использованию код, который решает это? Я могу, конечно, написать собственный материал для сохранения сеанса, а опция auto_prepend, указанная Грегом, кажется многообещающей - но это будет похоже на переосмысление колеса.:П
Добавлено 2: Балансировка нагрузки основана на DNS. Я не уверен, как это работает, но я думаю, что это должно быть что-то вроде this.
Добавлено 3: ОК, я вижу, что одним из решений является использование опции auto_prepend для вставки вызова в session_set_save_handler() в каждом script и написания моего собственного БД-клиента, возможно, для вызова вызовов memcached для лучшей производительности. Достаточно справедливо.

Есть ли способ, которым я мог бы вообще не кодировать все это? Как какой-то известный и проверенный PHP-плагин?

Добавлено много, намного позже: В конце концов я пошел: Как правильно реализовать пользовательский сеансовый persister в PHP + MySQL?

Кроме того, я просто включил обработчик сеанса вручную на всех страницах.

4b9b3361

Ответ 1

Вы можете настроить PHP для обработки сеансов в базе данных, поэтому все ваши серверы используют одну и ту же информацию о сеансе, так как все серверы используют для этого одну и ту же базу данных.

Хороший учебник для этого может быть найден здесь.

Ответ 2

Как мы справляемся с этим, это memcached. Все, что требуется, - это изменение php.ini, похожее на следующее:

session.save_handler = memcache
session.save_path = "tcp://path.to.memcached.server:11211"

Мы используем AWS ElastiCache, поэтому путь к серверу - это домен, но я уверен, что он будет похож на локальный memcached.

Этот метод не требует изменений кода приложения.

Ответ 3

Вы не упомянули, какую технологию вы используете для балансировки нагрузки (программное обеспечение, аппаратное обеспечение и т.д.); но в любом случае решение вашей проблемы заключается в использовании "липких сеансов" на балансировщике нагрузки.

Таким образом, это означает, что, когда приходит первый запрос от "нового" посетителя, ему назначается конкретный сервер из кластера: все будущие запросы на время жизни их сеанса затем направляются на этот сервер. На практике это означает, что приложения, написанные для работы на одном сервере, могут быть масштабированы до сбалансированной среды с нулевыми/небольшими изменениями кода.

Если вы используете аппаратный балансир, такой как устройство Radware, то липкие сеансы настроены как часть настройки кластера. Аппаратные устройства обычно предоставляют вам более мелкомасштабный контроль: например, какой сервер назначается новому пользователю (они могут проверять состояние работоспособности и т.д. И выбирать самый здоровый/наименее используемый сервер) и больше контролировать то, что происходит, когда сервер выходит из строя и выходит из кластера. Недостатком аппаратных балансиров является стоимость, но они стоят того, что имхо.

Что касается программных балансиров, это сводится к тому, что вы используете. Для Apache существует свойство stickysession на mod_proxy - и много статей через google, чтобы заставить это работать с php-сессией (например)


Изменить: Из других комментариев, отправленных после исходного вопроса, похоже, что ваш "балансировка" выполняется через Round Robin DNS, поэтому вышеупомянутое, вероятно, не будет применяться. Я воздержусь от комментариев дальше и начну пламя против круглых dns.

Ответ 4

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

Если вы все еще хотите использовать session_set_save_handler, то можете взглянуть на auto_prepend.

Ответ 5

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

По существу для каждой страницы мы проверяем, знаем ли мы идентификатор сеанса. Если мы не проверим, находимся ли мы в ситуации, о которой вы описали, проверяя, сохранены ли в памяти данные sesion. В противном случае мы просто начинаем новый сеанс.

Очевидно, для этого требуется, чтобы все соответствующие данные были скопированы в БД, но если вы инкапсулируете свои данные сеанса в отдельный класс, тогда он работает нормально.

Ответ 6

вы также можете попробовать использовать memcache в качестве обработчика сеанса

Ответ 7

Если вы используете сеансы php, вы можете поделиться с NFS в каталоге /tmp, где, я думаю, сеансы хранятся между всеми серверами в кластере. Таким образом вам не нужна база данных.

Отредактировано: вы также можете использовать внешнюю службу, например memcachedb (постоянную и быструю), и сохранять информацию о сеансе в индексе memcachedb и указывать его с помощью хэша содержимого или даже идентификатора сеанса.

Ответ 8

Если у вас есть время, и вы все еще хотите проверить больше решений, взгляните на http://redis4you.com/articles.php?id=01..

Использование redis является отказоустойчивым. С моей точки зрения, это может быть лучше, чем решения memcache из-за этой надежности.

Ответ 9

Возможно, слишком поздно, но проверьте это: http://www.pureftpd.org/project/sharedance

Sharedance - это высокопроизводительный сервер для централизации эфемерных ключей/данных пар на удаленных хостах, без накладных расходов и сложности SQL базы данных.

В основном он предназначен для совместного использования кешей и сеансов между пулом веб-сайтов сервера. Доступ к серверу обмена данными является тривиальным с помощью простого PHP API и он совместим с ожиданиями обработчиков сеансов PHP 4 и PHP 5.

Ответ 10

Когда дело доходит до обработки сеанса php в кластере балансировки нагрузки, лучше всего иметь Sticky Sessions. Для этого спросите сеть центра обработки данных, которая поддерживает балансировщик нагрузки, чтобы включить липкую сессию. Когда это будет разрешено, вам не нужно беспокоиться о сеансах на php end