Несколько веб-серверов PHP для совместного использования одного сервера Redis для пользовательских сессий - PullRequest
1 голос
/ 29 марта 2019

У меня есть 2 веб-сервера под управлением PHP и Nginx ... И у меня есть 1 Redis Server.Я хочу, чтобы веб-серверы использовали базу данных Redis для данных входа пользователя.Это позволит мне масштабировать веб-серверы, не заставляя вошедших в систему пользователей повторно проходить аутентификацию, если / когда они подключаются к новому серверу.

Оба сервера PHP / Nginx используют Redis для обработки сеансов, и оба ониуказать на ту же базу данных Redis.Когда я захожу на какой-либо сайт в моем браузере, он генерирует токен сеанса и сохраняет его в Redis (всего создается два ключа Redis) .... Но я хочу создать новый сеанс при посещении сайта № 1, хранитьсеанс в Redis, и сайт № 2 узнает меня при посещении, поскольку он запрашивает Redis (так что всего один ключ Redis).

Все 3 моих сервера находятся в AWS, в одном и том же VPC,Я использую внутренние IP-адреса для связи ч / б с веб-серверами и Redis (таким образом, ч / б есть некоторое доверие к ч / б машинам).

Я явно что-то здесь упускаю, и это может бытьбалансировщик нагрузки (который я буду реализовывать).Но я пытался разработать дизайн для совместного использования Redis с минимальным количеством компонентов.Кроме того, я не совсем уверен, что с этой проблемой помогает балансировщик нагрузки.

Вот соответствующие части кода:

Серверы PHP / Nginx: (x2)

(1) /etc/php/7.2/fpm/php.ini

session.save_handler = redis
session.save_path = "tcp://10.xxx.xx.xxx:6379" // both web servers point to the same Redis IP address

(2) /var / www / html / test.php

<code><?php 

ini_set('session.save_handler', 'redis'); // redundant; including for completeness
ini_set('session.save_path', 'tcp://10.xxx.xx.xxx:6379'); // redundant; including for completeness

session_name('FOOBAR');
session_start();
echo nl2br(
    '<pre>' . session_save_path() . '
'.PHP_EOL);echo nl2br ('Запуск версии PHP:'. phpversion (). PHP_EOL);if (! array_key_exists ('visit', $ _SESSION)) {$ _SESSION ['visit'] = 0;} $ _SESSION ['visit'] ++;echo nl2br ('Вы были здесь'. $ _SESSION ['visit']. 'times.');

Сервер Redis: (x1)

(3) /etc/redis/redis.conf

bind 0.0.0.0

Когда я попадаю на страницу test.php для обоих сайтов, они успешно генерируют и сохраняют свой собственный сеанс в базе данных Redis.И они правильно увеличивают свой соответствующий токен сеанса ... Но я хочу, чтобы эти веб-серверы обменивались с ними данными сеанса Redis, чтобы они "запоминали" всех вошедших в систему пользователей (даже если пользователь впервые посещает данный веб-сайт).сервер).

Спасибо!


РЕДАКТИРОВАТЬ: Я также попытался вручную запросить Redis для зарегистрированных пользовательских данных.Это дало результаты, аналогичные test.php выше.Каждый сайт заканчивал тем, что создавал и управлял собственным токеном сессии.

Серверы PHP / Nginx: (x2)

(4)/var/www/html/redis-check.php

<?php

   $cookie = "PHPREDIS_SESSION:" . $_COOKIE['FOOBAR'];

   // Connecting to Redis server on localhost 
   $redis = new Redis(); 
   $redis->connect('10.xxx.xx.xxx', 6379); 
   echo "Connection to server sucessfully";
   echo '<br />';

   // Check if cookie value exists in Redis 
   $seenuser = $redis->get($cookie);

   if( !empty($seenuser) )
   {
      echo 'Hello, old friend!<br />';
      echo '<br />';
      echo 'Cookie Value: ' . $cookie;
      echo '<br />';
      echo 'Session Value: ' . $seenuser;
   }
   else
   {
      // This is a new user, so create a new session
      ini_set('session.save_handler', 'redis'); // redundant; including for completeness
      ini_set('session.save_path', 'tcp://10.xxx.xx.xxx:6379'); // redundant; including for completeness
      session_name('FOOBAR');
      session_start();

      if (!array_key_exists('visit', $_SESSION))
      {
          $_SESSION['visit'] = 0;
      }
      $_SESSION['visit']++;

      $cookie = "PHPREDIS_SESSION:" . $_COOKIE['FOOBAR'];
      $seenuser = $redis->get($cookie);

      echo 'New Login<br />';
      echo '<br />';
      echo 'Cookie Value: ' . $cookie;
      echo '<br />';
      echo 'Session Value: ' . $seenuser;
   }

1 Ответ

0 голосов
/ 30 марта 2019

Похоже, что моя проблема произошла из-за отсутствия балансировщика нагрузки. Я поставил HAProxy перед моими двумя веб-серверами, указал на адрес HAProxy в броузере, и веб-серверы немедленно начали обмениваться данными сеанса. хранится в Redis. Я предполагаю, что они оба используют адрес HAProxy. И мой браузер (Chrome) показывает только один файл cookie для адреса HAProxy (что я и хочу) ... Когда я обхожу HAProxy и указываю на веб-серверы прямо в браузере, они генерируют свой собственный токен сеанса (что плохо для этот сценарий).

Итак, вот соответствующие разделы кода (вы можете не обращать внимания на то, что в моем ОП):

Серверы PHP / Nginx: (x2)

(1) /etc/php/7.2/fpm/php.ini

session.save_handler = redis
session.save_path = "tcp://10.xxx.xx.xxx:6379" // both web servers point to the same Redis IP address

(2) /var/www/html/test.php

<?php

session_name('FOOBAR');
session_start();

echo 'IP Address: ' . getHostByName(getHostName());
echo '<br />';
echo '*******************************************************************************';
echo '<br />';

if (!array_key_exists('visit', $_SESSION))
{

    $_SESSION['visit'] = 0;

    echo 'Hello, new friend!';
    echo '<br />';
}
else
{

    echo 'Glad you are still with us!!';
    echo '<br />';
}

$_SESSION['visit']++;

echo 'You have been here ' . $_SESSION['visit'] . ' times.';

Сервер Redis: (x1)

(3) /etc/redis/redis.conf

bind 0.0.0.0

Сервер HA: (x1)

(4) /etc/haproxy/haproxy.cfg

frontend proxy_in
    bind *:80
    default_backend web_farm

backend web_farm
    balance roundrobin
    mode http
    server web1 10.xxx.xx.111:80 check  # web server 1
    server web2 10.xxx.xx.222:80 check  # web server 2

Серверы PHP / Nginx: (x2)

/ вар / WWW / HTML / Redis-check.php

Ignore this file. The revised test.php file is all that is needed.

Найджел и Саад, спасибо за ссылки! всегда хорошо, чтобы получить другой POV по этой проблеме.

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