gpt4 book ai didi

php - 多个 PHP Web 服务器为用户 session 共享一个 Redis 服务器

转载 作者:IT王子 更新时间:2023-10-29 06:07:13 24 4
gpt4 key购买 nike

我有 2 台运行 PHP 和 Nginx 的网络服务器……我有 1 台 Redis 服务器。我希望 Web 服务器将 Redis 数据库用于用户登录数据。这将允许我扩展 Web 服务器,而无需强制登录用户在/当他们访问新服务器时重新进行身份验证。

两个 PHP/Nginx 服务器都使用 Redis 进行 session 处理,并且它们都指向同一个 Redis 数据库。当我在浏览器中访问任一站点时,它会生成一个 session token 并将其存储在 Redis 中(总共创建两个 Redis key )...... 但我想要的是在访问站点 #1 时创建一个新 session ,存储Redis 中的 session ,并让站点 #2 在我访问时认出我,因为它查询 Redis(因此总共只有一个 Redis key )。

我的所有 3 个服务器都在 AWS 中,在同一个 VPC 中。我正在使用内部 IP 地址与 Web 服务器和 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

<?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() . '</pre>' . PHP_EOL
);

echo nl2br(
'Running PHP version: ' . phpversion() . PHP_EOL
);

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

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

Redis 服务器:(x1)

(3)/etc/redis/redis.conf

bind 0.0.0.0

当我点击两个站点的 test.php 页面时,它们成功生成了自己的 session 并将其存储在 Redis 数据库中。他们正确地增加了他们各自的 session token ......但我希望这些网络服务器与他们共享Redis session 数据,所以他们“记住”所有登录的用户(即使这是用户第一次访问给定的网络服务器)。

谢谢!


编辑:我还尝试手动查询 Redis 以获取登录用户数据。这产生了与上面的 test.php 相似的结果。每个网站最终都会创建和管理自己的 session token 。

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;
}

最佳答案

看起来我的问题是由于缺少负载均衡器造成的。我将 HAProxy 放在我的两个 Web 服务器前面,在浏览器中指向 HAProxy 的地址,Web 服务器立即开始共享 session 数据存储在 Redis 中。我猜他们都在使用 HAProxy 地址。我的浏览器 (Chrome) 只显示一个 cookie 用于 HAProxy 地址(这是我想要的)...当我绕过 HAProxy 并直接在浏览器中指向 Web 服务器时,它们会生成自己的 session token (这对这种情况)。

这里是相关的代码部分 (你可以忽略我的 OP 中的内容):

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)

/var/www/html/redis-check.php

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

Nigel 和 Saad,感谢您提供的链接!在问题上获得不同的视角总是是件好事。

关于php - 多个 PHP Web 服务器为用户 session 共享一个 Redis 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55412086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com