如何在Ubuntu16.04上将Redis服务器设置为PHP的会话处理程序

来自菜鸟教程
跳转至:导航、​搜索

介绍

Redis 是一个开源的键值缓存和存储系统,由于其对多种数据类型(例如哈希、列表、集合和位图等)的高级支持,也被称为数据结构服务器。 它还支持集群,使其在高可用性和可扩展的环境中非常有用。

在本教程中,我们将了解如何安装和配置外部 Redis 服务器以用作在 Ubuntu 16.04 上运行的 PHP 应用程序的会话处理程序。

会话处理程序负责存储和检索保存到会话中的数据。 默认情况下,PHP 为此使用 files。 这对于单个服务器来说足够好,但由于会话信息与单个服务器相关联,因此具有一些显着的性能和可伸缩性限制。

外部会话处理程序为多个应用程序服务器可以使用的共享会话数据提供了一个中心位置。 在 负载平衡器 后面创建 可扩展 PHP 环境 时,这一点很重要,因为无论哪个应用程序服务器为单个请求提供服务,相同的会话数据都将可用。

先决条件

本教程将使用两台服务器配置会话处理。 要继续进行,您将需要:

  • 在 Ubuntu 16.04 上运行 LAMPLEMP 的 PHP Web 服务器。 我们将此服务器称为 web
  • 第二个干净的 Ubuntu 16.04 服务器将安装 Redis。 我们将此服务器称为 redis

您需要在每台服务器上配置具有 sudo 权限的非 root 用户。 我们还将假设每个服务器都有一个基本的防火墙在运行。 您可以按照我们的 Ubuntu 16.04 初始服务器设置指南 在两台服务器上设置这两个要求。

步骤 1:安装 Redis 服务器和客户端软件

我们的第一步是在我们的两台机器上安装必要的软件。 我们的 redis 机器需要一个 Redis 服务器。 在我们的 web 机器上,我们将安装用于会话处理的 Redis PHP 扩展和用于测试的 Redis 命令行客户端。

安装 Redis 服务器

我们需要做的第一件事是让 Redis 服务器在我们的 redis 机器上运行。

我们将使用常规的 Ubuntu 包管理器和 Chris Lea 提供的受信任的 PPA 存储库。 这是确保我们获得最新稳定版本的 Redis 所必需的。

注意: 作为一般安全建议,您应该只使用来自受信任来源的 PPA。


首先,通过运行添加 PPA 存储库:

sudo apt-add-repository ppa:chris-lea/redis-server

ENTER 确认。

接下来,更新包索引并通过键入以下命令安装 Redis 服务器:

sudo apt-get update
sudo apt-get install redis-server

Redis 现在应该已安装并在您的服务器上运行。 通过键入以下内容测试服务是否正在运行并接受连接:

redis-cli ping
Redis server outputPONG

这将连接到端口 6379 上在 localhost 上运行的 Redis 实例。 您应该得到 PONG 作为响应。

安装 Redis 客户端和 PHP 扩展

接下来,在 web 服务器上安装 Redis 命令行客户端和 Redis PHP 扩展。 我们将使用命令行客户端轻松测试连接性和身份验证。 我们将使用 PHP 扩展来存储我们的会话数据。

更新本地包索引并在您的 web 服务器上安装软件,方法是键入:

sudo apt-get update
sudo apt-get install redis-tools php-redis

您现在应该可以访问 redis-cli 工具,尽管您还不能访问要测试的服务器。

第 2 步:配置 Redis 以接受外部连接

默认情况下,Redis 只允许来自 localhost 的连接,这基本上意味着您只能从安装 Redis 的服务器内部进行访问。 我们需要更改此配置以允许来自其他服务器的连接。

Redis 不提供本机加密选项,并假定它已部署到受信任对等点的隔离网络。 这意味着要安全地允许外部连接,两个服务器必须位于隔离网络上,或者您需要以另一种方式保护它们之间的流量。

如果 Redis 部署到隔离网络……

如果您的服务器在隔离网络中运行,您可能只需要调整 Redis 的配置文件以绑定到您的隔离网络 IP 地址。

redis 服务器上,备份并打开 Redis 配置文件:

sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sudo nano /etc/redis/redis.conf

找到 bind 行并附加 Redis 服务器的隔离网络 IP 地址:

/etc/redis/redis.conf

bind 127.0.0.1 isolated_IP_address

保存并关闭文件。 通过键入以下内容重新启动服务:

sudo systemctl restart redis-server.service

打开对 Redis 端口的访问:

sudo ufw allow 6379

Redis 现在能够接受来自隔离网络的连接。

如果 Redis 没有部署到隔离网络……

对于未隔离或您无法控制的网络,必须通过其他方式保护流量。 有许多选项可以保护 Redis 服务器的流量,包括:

  • Tunneling with stunnel:您需要在 redis 服务器上设置一个传入隧道,在 web 服务器上设置一个传出隧道。 Web 服务器将连接到本地端口以与远程 Redis 服务进行通信。
  • 使用 spiped 建立隧道:web 服务器应充当 spiped 客户端计算机。 您需要在每台服务器上创建一个 systemd 单元文件。 Web 服务器将连接到本地端口以与远程 Redis 服务进行通信。
  • 使用 PeerVPN 设置 VPN:两台服务器都需要在 VPN 上可访问。 web 服务器将能够使用其 VPN IP 地址访问 redis 服务器。

使用上述方法之一,配置从 web 服务器到 redis 服务器的安全访问。 您需要知道 web 机器用于连接远程机器上的 Redis 服务的 IP 地址和端口。

此时,您应该能够从 Web 服务器安全地访问您的 Redis 服务器。

步骤 3:为 Redis 服务器设置密码

要为您的 Redis 安装添加额外的安全层,建议您设置访问服务器数据的密码。 我们将在 /etc/redis/redis.conf 编辑 Redis 配置文件:

sudo nano /etc/redis/redis.conf

找到 requirepass 指令并将其设置为强密码。 虽然您的 Redis 流量应该不受外部各方的影响,但这为 Redis 本身提供了身份验证。 由于 Redis 速度很快并且不会限制密码尝试,因此请选择一个强大、复杂的密码来防止暴力尝试:

/etc/redis/redis.conf

requirepass yourverycomplexpasswordhere

完成后保存并关闭文件。

重新启动 Redis 服务以实现更改:

sudo systemctl restart redis-server.service

您的 Redis 服务器现在应该拒绝未经身份验证的请求。

第 4 步:测试 Redis 连接和身份验证

要测试您的更改是否按预期工作,请从 web 机器连接到 Redis 服务。

默认情况下,Redis 服务器在本地接口上侦听 6379,但是我们上面介绍的每个网络安全选项都会以某种方式为外部各方修改默认值。 我们可以使用 redis-cli 客户端和 -h 选项来指定 IP 地址和 -p 选项来指定连接到远程服务所需的端口。 如果它们使用默认选项(分别为 127.0.0.1 和 6379),您可以省略其中任何一个。

您使用的值取决于您用于保护网络流量的方法:

  • 隔离网络:使用Redis服务器的隔离网络IP地址。 使用了默认的Redis端口(6379),我们就不用提了:redis-cli -h redis_isolated_IP
  • stunnelspiped:使用隧道到远程 Redis 服务的本地端口:redis-cli -p 8000
  • PeerVPN:使用Redis服务器的VPN IP地址:redis-cli -h 10.8.0.1

一般形式为:

redis-cli -h ip_to_contact_redis -p port_to_contact_redis

您应该能够从 web 服务器连接到远程 Redis 实例。

如果您定义了密码并现在尝试访问数据,您应该会收到一个 AUTH 错误:

keys *
Web server output(error) NOAUTH Authentication required.

要进行身份验证,您只需运行 AUTH 命令,提供您在 /etc/redis/redis.conf 文件中定义的相同密码:

AUTH yourverycomplexpasswordhere

您应该得到一个 OK 作为响应,表明您的凭据已被接受。

Web server outputOK

接下来,列出在 Redis 中设置的键:

keys *

如果这是一个新的 Redis 服务器,输出应该类似于:

Web server output(empty list or set)

这个输出仅仅意味着你的 Redis 服务器是空的,这正是我们所期望的。 web 服务器尚未配置为将此 Redis 服务器用作会话处理程序。

通过键入以下命令退出到命令 shell:

exit

现在我们已经验证了我们可以通过身份验证成功连接,我们可以将 Redis 作为我们的默认会话处理程序。

第 5 步:将 Redis 设置为 Web 服务器上的默认会话处理程序

现在我们需要编辑 web 服务器上的 php.ini 文件来更改 PHP 的默认会话处理程序。 该文件的位置将取决于您当前的堆栈。

对于从默认存储库安装的 Ubuntu 16.04 上的 LAMP 堆栈,这通常是 /etc/php/7.0/apache2/php.ini。 对于 Ubuntu 16.04 上的 LEMP 堆栈,路径通常是 /etc/php/7.0/fpm/php.ini。 如果您已验证其中一个位置是正确的,请随时跳过下一部分。

(可选)找到正确的 php.ini 文件

如果您不确定主 php.ini 文件的位置,可以使用 phpinfo() 函数查找。 在文档根目录中打开 web 服务器上名为 info.php 的文件,对于 LAMP 和 LEMP,默认情况下为 /var/www/html

sudo nano /var/www/html/info.php

将以下代码放入文件中:

/var/www/html/info.php

<?php
phpinfo();

在浏览器中访问您的web服务器的域名或IP地址,然后是/info.php

http://web_server_domain_or_IP/info.php

查找包含“已加载配置文件”的行,您应该找到加载的主 php.ini 的确切位置。

完成后删除该文件,因为它会显示有关您的环境的敏感信息:

sudo rm /var/www/html/info.php

现在您知道文件的位置,您可以继续编辑。

修改配置

打开 php.ini 文件进行编辑。

如果您在默认配置中使用 LAMP 堆栈,您需要的命令是:

sudo nano /etc/php/7.0/apache2/php.ini

如果您在其默认配置中使用 LEMP 堆栈,您需要的命令是:

sudo nano /etc/php/7.0/fpm/php.ini

如果您使用上述 phpinfo() 方法发现了不同的路径,请在此处替换该路径。

php.ini 文件中,搜索包含 session.save_handler 的行。 默认值为 files。 将此更改为 redis 以使用 Redis PHP 扩展。

[label php.ini] 
session.save_handler = redis

接下来,找到包含 session.save_path 的行。 您需要取消注释并更改值,使其包含您的 Redis 连接字符串。

可以使用以下格式构造连接字符串,全部在一行中:

tcp://IP_address:port?auth=redis_password

同样,正确的值将取决于您选择的安全网络策略。 使用您之前提供给 redis-cli 命令的相同值。 例如,如果您使用 stunnelspiped,则 session.save_path 可能看起来像这样:

[label php.ini] 
session.save_path = "tcp://127.0.0.1:8000?auth=yourverycomplexpasswordhere"

完成后保存并关闭文件。 接下来,重新启动 PHP 服务以实现您的更改。

LAMP 环境中,键入:

sudo systemctl restart apache2

LEMP 环境中,键入:

sudo systemctl restart php7.0-fpm

PHP 现在应该配置为使用 Redis 作为会话处理程序。

第 6 步:测试 Redis 会话处理

为确保您的会话现在由 Redis 处理,您需要一个 PHP 脚本或应用程序在会话中存储信息。 我们将使用一个实现计数器的简单脚本。 每次重新加载页面时,打印的数字都会增加。

在文档根文件夹内的 web 服务器上创建一个名为 test.php 的文件:

sudo nano /var/www/html/test.php

在里面,粘贴以下代码:

[label /var/www/html/test.php] 
<?php
//simple counter to test sessions. should increment on each page reload.
session_start();
$count = isset($_SESSION['count']) ? $_SESSION['count'] : 1;

echo $count;

$_SESSION['count'] = ++$count;

保存并关闭文件。

将浏览器指向 web 服务器的公共 IP 地址,后跟 /test.php 以访问脚本:

http://web_server_public_IP/test.php

每次重新加载页面时,它应该增加您看到的数字。

现在,在您的 redis 机器上,使用 redis-cli 打开一个会话。 由于我们连接到本地实例,我们不必提供 IP 地址或端口:

redis-cli

使用 Redis 密码进行身份验证:

AUTH yourverycomplexpasswordhere
Redis server outputOK

现在,检查现有密钥:

keys *

您应该会看到我们的 PHP 会话的新条目:

Redis server output1) "PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800"

如果您询问键的值,您应该能够看到当前的计数器值:

get PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800
Redis server output"count|i:6;"

这表明会话信息正在存储在 Redis 服务器上。 您可以将其他 Web 服务器连接到 Redis 服务器以进行集中式会话管理。

结论

Redis 是一种功能强大且快速的键值存储服务,也可以用作 PHP 的会话处理程序,通过提供分布式会话存储系统来实现可扩展的 PHP 环境。 更多关于扩展 PHP 应用程序的信息,可以查看这篇文章:水平扩展 PHP 应用程序