介绍
Redis 是一个开源的关键值缓存和存储系统,也被称为数据结构服务器,因为它对多个数据类型,如哈希,列表,集和比特图等先进的支持。
在本教程中,我们将看到如何安装和配置外部 Redis 服务器,以作为 Ubuntu 16.04 上运行的 PHP 应用程序的会话处理器。
会话处理器负责存储和检索在会话中保存的数据. 默认情况下,PHP 使用 ** 文件**。 这对于单个服务器来说足够好,但存在一些显著的性能和可扩展性限制,因为会话信息绑定到单个服务器。
外部会话处理器为共享会话数据提供了一个中央位置,可以由多个应用程序服务器使用,这在创建 可扩展的PHP环境后面 负载平衡器时很重要,因为相同的会话数据将可用,无论哪个应用程序服务器为单个请求提供服务。
前提条件
本教程将配置使用两个服务器的会话处理。
您需要在每个服务器上配置sudo
权限的非根用户,我们还将假定每个服务器都有运行基本的防火墙,您可以按照我们的 Ubuntu 16.04初始服务器设置指南在两个服务器上设置这两个要求。
步骤 1:安装 Redis 服务器和客户端软件
我们的第一步将是将所需的软件安装在我们的两台机器上。我们的 redis 机器将需要一个 Redis 服务器。在我们的 web 机器上,我们将安装 Redis PHP 扩展来处理会话和 Redis 命令行客户端进行测试。
安装 Redis 服务器
我们需要做的第一件事是让 Redis 服务器在我们的 redis 机器上运行。
我们将使用常规的Ubuntu包管理器与由Chris Lea提供的可信的PPA存储库,这是必要的,以确保我们得到最新的稳定版本的Redis。
<$>[注] 注: 作为一般的安全建议,您只应该使用来自可信来源的PPA。
首先,通过运行添加 PPA 存储库:
1[environment second]
2sudo apt-add-repository ppa:chris-lea/redis-server
点击进入
来确认。
接下来,更新包索引并通过键入安装 Redis 服务器:
1[environment second]
2sudo apt-get update
3sudo apt-get install redis-server
Redis 现在应该安装并在您的服务器上运行。 通过键入测试该服务是否正在运行并接受连接:
1[environment second]
2redis-cli ping
1[environment second]
2[secondary_label Redis server output]
3PONG
这将连接到运行在 localhost 端口 6379上的 Redis 实例。
安装 Redis 客户端和 PHP 扩展
接下来,安装 Redis 命令行客户端和 Redis PHP 扩展到 web 服务器上。我们将使用命令行客户端来轻松测试连接性和身份验证。
更新本地包索引并在您的 web服务器上安装软件,键入:
1[environment third]
2sudo apt-get update
3sudo apt-get install redis-tools php-redis
您现在应该可以访问redis-cli
工具,尽管您还没有访问服务器来测试。
步骤 2:配置 Redis 以接受外部连接
默认情况下,Redis只允许来自本地主机
的连接,这基本上意味着您只能从安装Redis的服务器内部访问。
Redis 不提供原生加密选项,并假定它已部署到一个由可信同行组成的孤立网络中,这意味着为了安全地允许外部连接,无论是两个服务器都必须在一个孤立的网络上,还是您需要以其他方式确保它们之间的流量。
如果 Redis 部署到一个孤立的网络...
如果您的服务器运行在一个孤立的网络中,您可能只需要调整 Redis 的配置文件以连接到您的孤立的网络 IP 地址。
在 redis 服务器上,备份并打开 Redis 配置文件:
1[environment second]
2sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
3sudo nano /etc/redis/redis.conf
查找绑定
行,并附上 Redis 服务器的孤立网络 IP 地址:
1[environment second]
2[label /etc/redis/redis.conf]
3bind 127.0.0.1 isolated_IP_address
保存并关闭文件. 重启服务,键入:
1[environment second]
2sudo systemctl restart redis-server.service
打开 Redis 端口:
1[environment second]
2sudo ufw allow 6379
Redis 现在可以接受来自您的孤立网络的连接。
如果 Redis 没有部署到一个孤立的网络...
对于未被孤立或您无法控制的网络,必须通过其他方式确保流量。
- Tunneling with stunnel:您将需要在 redis服务器上设置入口隧道和在 web服务器上设置入口隧道。 Web 服务器将连接到本地端口以与远程 Redis 服务进行通信。
- Tunneling with spiped: web服务器应作为
spiped
客户端机器运作。您将需要在每个服务器上创建一个 systemd 单元文件。 Web 服务器将连接到本地端口以与远程 Redis 服务进行通信。 - 设置与 PeerVPN 的 VPN:这两个服务器都需要在 VPN 上可访问。 web服务器将能够使用其 VPN 地址
使用上述方法之一,从您的 web服务器配置安全访问到您的 redis服务器. 您需要知道您的 web 机器将使用的 IP 地址和端口连接到远程机器上的 Redis 服务。
在此时,您应该能够安全地从 Web 服务器访问您的 Redis 服务器。
步骤 3:为 Redis 服务器设置密码
为了为您的 Redis 安装添加一个额外的安全层,建议您为访问服务器数据设置密码. 我们将编辑 Redis 配置文件在 /etc/redis/redis.conf
:
1[environment second]
2sudo nano /etc/redis/redis.conf
查找requirepass
指令并将其设置为强有力的密码短语,而您的 Redis 流量应该受到外部人员的保护,这为 Redis 提供身份验证,因为 Redis 是快速的,并且不限制密码尝试,选择强有力的、复杂的密码短语来保护您免受暴力攻击:
1[environment second]
2[label /etc/redis/redis.conf]
3requirepass yourverycomplexpasswordhere
保存并关闭文件,当你完成。
重新启动 Redis 服务以实现更改:
1[environment second]
2sudo systemctl restart redis-server.service
您的 Redis 服务器现在应该拒绝未经验证的请求。
步骤 4:测试 Redis 连接和身份验证
要测试您的更改是否按预期工作,请从 web 机器连接到 Redis 服务。
默认情况下,Redis服务器在本地界面上收听6379,但我们上面提到的每个网络安全选项都会以某种方式改变对外部方的默认。我们可以使用redis-cli
客户端与h
选项来指定IP地址和p
选项来指定连接到远程服务所需的端口。
您使用的值将取决于您用来保护网络流量的方法:
- 隔离网络: 使用 Redis 服务器的隔离网络 IP 地址. 使用了默认的 Redis 端口(6379),所以我们不需要提及它:
redis-cli -h redis_isolated_IP
- stunnel 或 spiped: 使用向远程 Redis 服务隧道的本地端口:
redis-cli -clip 8000
- PeerVPN: 使用 Redis 服务器的 VPN IP 地址:
redis-cli -h 10.8.0.1
一般形式是:
1[environment third]
2redis-cli -h ip_to_contact_redis -p port_to_contact_redis
您应该能够从 web 服务器连接到远程 Redis 实例。
如果您定义了密码,现在尝试访问数据,您应该收到 AUTH 错误:
1[environment third]
2keys *
1[environment third]
2[secondary_label Web server output]
3(error) NOAUTH Authentication required.
要验证,您只需要运行AUTH
命令,提供您在/etc/redis/redis.conf
文件中定义的相同密码:
1[environment third]
2AUTH yourverycomplexpasswordhere
您应该收到一个 OK作为回复,表示您的凭证已被接受。
1[environment third]
2[secondary_label Web server output]
3OK
接下来,列出 Redis 中设置的键:
1[environment third]
2keys *
如果这是新鲜的 Redis 服务器,输出应该是这样的:
1[environment third]
2[secondary_label Web server output]
3(empty list or set)
此输出只是意味着您的 Redis 服务器是空的,这正是我们所期望的。
退出返回命令壳,键入:
1[environment third]
2exit
现在我们已经验证了我们可以成功连接到身份验证,我们可以让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()
函数来找到它。在你的文档根中打开一个名为 info.php
的文件在你的 web 服务器上,默认情况下它将是 /var/www/html
对于 LAMP 和 LEMP:
1[environment third]
2sudo nano /var/www/html/info.php
将下列代码放入文件中:
1[environment third]
2[label /var/www/html/info.php]
3<?php
4phpinfo();
在您的浏览器中访问您的 web服务器的域名或 IP 地址,然后是 /info.php
:
1http://web_server_domain_or_IP/info.php
寻找包含加载配置文件
的行,你应该找到加载的主要php.ini
的确切位置。
完成后,请删除该文件,因为它会显示有关您的环境的敏感信息:
1[environment third]
2sudo rm /var/www/html/info.php
现在你知道文件位于何处,你可以继续编辑。
更改配置
打开php.ini
文件进行编辑。
如果您在默认配置中使用了 LAMP 堆栈,您需要的命令是:
1[environment third]
2sudo nano /etc/php/7.0/apache2/php.ini
如果您在默认配置中使用了 ** LEMP** 堆栈,您需要的命令是:
1[environment third]
2sudo nano /etc/php/7.0/fpm/php.ini
如果您使用上面描述的 phpinfo()
方法发现了不同的路径,请替代此路径。
在php.ini
文件中,搜索包含session.save_handler
的行。默认值是files
。更改为redis
以使用 Redis PHP 扩展。
1[environment third]
2[label php.ini]
3session.save_handler = redis
接下来,找到包含session.save_path
的行,您需要删除评论并更改值,以便包含您的 Redis 连接字符串。
连接字符串可以使用以下格式构建,全部在一行:
1tcp://IP_address:port?auth=redis_password
再一次,正确的值将取决于您选择的安全网络策略。 使用您之前向redis-cli
命令提供的相同值。 例如,如果您使用了stunnel
或spiped
,则session.save_path
可能会看起来像这样:
1[environment third]
2[label php.ini]
3session.save_path = "tcp://127.0.0.1:8000?auth=yourverycomplexpasswordhere"
完成后,保存并关闭文件,然后重新启动PHP服务以实现更改。
在 LAMP环境中,类型:
1[environment third]
2sudo systemctl restart apache2
在 LEMP 环境中,类型:
1[environment third]
2sudo systemctl restart php7.0-fpm
PHP 现在应该配置为使用 Redis 作为会话处理器。
步骤 6:测试 Redis 会议处理
为了确保您的会话现在由Redis处理,您将需要一个PHP脚本或应用程序,该程序在会话中存储信息。我们将使用一个简单的脚本,该脚本实现计数器。
在文档根文件夹内的 web服务器上创建一个名为 `test.php 的文件:
1[environment third]
2sudo nano /var/www/html/test.php
在里面,插入以下代码:
1[environment third]
2[label /var/www/html/test.php]
3<?php
4//simple counter to test sessions. should increment on each page reload.
5session_start();
6$count = isset($_SESSION['count']) ? $_SESSION['count'] : 1;
7
8echo $count;
9
10$_SESSION['count'] = ++$count;
保存并关闭文件。
将您的浏览器指向 web服务器的公共 IP 地址,然后是 `/test.php'以获取脚本:
1http://web_server_public_IP/test.php
它应该增加您每次重新加载页面时看到的数字。
现在,在您的 redis 机器上,使用redis-cli
打开会话. 由于我们正在连接到本地实例,我们不需要提供 IP 地址或端口:
1[environment second]
2redis-cli
使用 Redis 密码进行身份验证:
1[environment second]
2AUTH yourverycomplexpasswordhere
1[environment second]
2[secondary_label Redis server output]
3OK
现在,检查现有的密钥:
1[environment second]
2keys *
您应该看到我们的PHP会话的新条目:
1[environment second]
2[secondary_label Redis server output]
31) "PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800"
如果您询问密钥的值,您应该能够看到当前的计数值:
1[environment second]
2get PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800
1[environment second]
2[secondary_label Redis server output]
3"count|i:6;"
这表明会话信息正在存储在 Redis 服务器上,您可以连接额外的 Web 服务器到 Redis 服务器以进行集中式会话管理。
结论
Redis是一个强大而快速的关键值存储服务,也可以作为PHP的会话处理器使用,通过提供会话存储的分布式系统来实现可扩展的PHP环境。