返回博客

在 Ubuntu 20.04 上使用 Redis 实现 PHP 速率限制:教程

在 Ubuntu 20.04 上使用 Redis 实现 PHP 速率限制:教程

Redis,也称为 Remote Dictionary Server,是一个开源的内存数据库。它是一个运行在服务器 RAM 上的数据结构存储系统,这比最快的固态硬盘(SSD)还要快得多。因此,Redis 的响应速度非常快,非常适合用于速率限制。

速率限制 限制了用户向服务器请求资源的次数。许多服务使用速率限制来防止服务滥用,例如用户试图用过多的负载压垮服务器。例如,当使用 PHP 来为您的 Web 应用程序开发公共 API(应用程序编程接口)时,需要进行速率限制。这是因为当您向公众公开 API 时,您会希望限制个人在特定时间内重复某项活动的次数。对您的系统没有管理权限的用户可能会使其陷入停顿。

速率限制通过拒绝超过设定限制的用户请求,使您的应用程序能够平稳运行。如果您有大量客户端,速率限制会实施公平使用政策,允许每个用户以极快的速度访问您的应用程序。速率限制还可以通过减少服务器上的拥堵来帮助您节省带宽费用。

通过在诸如 MySQL 之类的数据库中跟踪用户活动,是可以创建速率限制程序的。然而,由于此类数据需要从磁盘下载并根据定义的限制进行评估,因此当多人同时访问系统时,最终结果可能无法扩展。这不仅效率低下,而且关系型数据库管理解决方案本来就不是为此而设计的。

Redis 是制作速率限制器的绝佳选择,因为它作为内存数据库运行,并且已被证明是可靠的。在本教程中,我们将引导您完成在 Ubuntu 20.04 上使用 Redis 实现 PHP 速率限制.

让我们开始吧!

前提条件

要学习本教程,您需要满足以下条件:

步骤 1:安装 PHP 的 Redis 扩展

在开始之前,让我们更新存储库以避免软件包冲突:

接下来,安装 php-redis 扩展,这是一个使在 PHP 程序中使用 Redis 成为可能的软件包。运行以下 sudo 命令来安装 php-redis:

之后,重启 Apache 服务器以加载 php-redis 库:

下一步是更新软件索引中的信息并安装 PHP 的 Redis 库。然后,我们将创建一个根据用户 IP 地址限制访问的 PHP 资源。

步骤 2:创建用于速率限制的 PHP Web 资源

在此步骤中,您将创建一个 demo.php 文件,位于 Web 服务器的根目录( /var/www/html/)中。该文件将向公众开放,用户将能够在他们首选的浏览器中启动该 URL。稍后,我们将使用 curl 命令来验证我们要使用的资源的可用性。用户可以在 15 秒的时间跨度内访问该示例资源文件三次。超过最大限制的尝试将抛出错误消息。

该文件的主要功能强烈依赖于 Redis 服务器。当用户首次访问资源时,文件中的 PHP 代码会根据用户的 IP 地址在 Redis 服务器上创建一个键。当用户再次访问该资源时,代码将尝试将用户的 IP 地址与 Redis 服务器中保存的键进行匹配,如果该键存在,则将其值增加 1。PHP 代码将持续检查新值是否已达到最大数量。

15 秒后,基于用户 IP 地址的 Redis 键将过期,系统将重新开始跟踪用户对 Web 资源的访问。打开 /var/www/html/demo.php 文件,在 nano 文本编辑器中:

然后,填写所有字段以初始化 Redis 类。不要忘记将 REDIS_PASSWORD 设置为正确的值:

Redis->auth 支持 Redis 服务器明文身份验证。如果您在本地(通过 localhost)工作,这非常有效,但如果您面对的是远程 Redis 服务器,SSL 身份验证 是推荐的做法。

接下来,在同一个文件中,将以下变量设置为它们的默认值:

让我们详细了解一下这些语句:

  • $max_calls_limit:用户访问该资源不能超过此最大调用限制。

  • $time_period:这用作时间范围,以秒为单位计算。在这里,允许用户根据 中设置的限制来访问资源$max_calls_limit .

  • $total_user_calls:累加用户在给定时间段内请求访问 调用 限制的次数。

然后,添加以下代码以获取请求访问网页的用户的 IP 地址:

作为演示,此代码通过用户的 IP 地址记录其操作。如果您的服务器上有需要身份验证的受保护资源,您可以使用其用户名或访问令牌来跟踪用户的操作。

在我们的指南中,登录到系统的每个用户都将被分配一个唯一标识(例如,客户 ID、开发人员 ID、供应商 ID 甚至用户 ID)。如果您正在按照我们的教程进行操作,请记住使用这些 ID 代替 $user_ip 地址,如果您正在按照我们的教程进行操作。

在这里,用户的 IP 地址足以演示该概念。从前面的代码片段中获取用户的 IP 地址后,将以下代码块添加到您的文件中:

以下是这些语句的概述:

  • if...else:该语句验证 Redis 服务器上是否定义了带有该 IP 地址的键。

    • 如果未找到该键,如果 (!$redis->exists($user_ip_address)) {...},您可以使用以下命令设置该键并将其值定义为 1: $redis->set($user_ip_address, 1).

  • $redis->expire($user_ip_address, $time_period):设置该键在指定时间过期。在本教程中,我们将其设置为 15 秒。

  • 如果在 Redis 键中未找到用户的 IP 地址,请将变量 $total_user_calls 设置为 1.

  • else {...}:该语句块使用 $redis->INCR($user_ip_address); 命令将 Redis 键的值递增 1。这将应用于与该键关联的每个 IP 地址。

    • 注意:只有当该键已在 Redis 服务器中设置并被视为重复请求时,才能实现此操作。

  • $total_user_calls = $redis->get($user_ip_address):该语句通过验证 Redis 服务器上各自基于 IP 地址的键来检索总请求数。

  • if ($total_user_calls > $max_calls_limit) {... }..:此 if 语句用于验证是否超出限制。如果是,您可以使用以下内容通知用户: echo "用户" . $user_ip_address . " 超过限制。";.

最后,您可以使用以下语句通知用户其在指定时间段内的访问次数: echo "欢迎" . $user_ip_address . "总调用次数" . $total_user_calls . "在" . $time_period . "秒内"; 语句。

之后,在您的 /var/www/html/demo.php 文件中:

保存并关闭 /var/www/html/demo.php 文件(在您完成修改后)。在 demo.php 网页上,您现在已经创建了限制用户速率所需的逻辑。让我们在下一步中测试我们的脚本。

步骤 3:运行 Redis 速率限制测试

您将在此步骤中使用 curl 命令来请求您在 步骤 2 中编写的 Web 资源。为了彻底测试该脚本,请发出一个请求该资源五次的命令。这可以通过向 添加占位符 URL 参数来实现 demo.php 文件的末尾。要执行 curl 指令五次,请使用值 ?[1-5] 在请求的末尾。

执行以下 curl 命令:

执行代码时,您应该会得到类似以下的内容:

如您所见,前三个请求顺利完成。然而,第四个和第五个查询被您的脚本限制了速率。Redis 服务器很有可能正在降低人们进行查询的速度。

您在本指南中为下面列出的两个变量指定了较低的值:

在生产环境中构建应用程序时,您可能需要考虑使用更大的数值,这取决于您认为人们使用它的频率。

在调整这些数字之前,最好先检查实时统计数据。在此示例中,如果您的服务器日志显示平均每个用户每 60 秒访问您的应用程序 1,000 次,则可以使用该数字作为要使用多少限制的示例。

结论

在本指南中,您学习了如何在 Ubuntu 20.04 上结合 PHP 使用 Redis 服务器。虽然本文演示了如何使用 Redis 进行速率限制,但您可以对其进行自定义以满足 Web 应用程序的需求。我们鼓励您探索实际示例,例如 Twitter 的最大请求限制, Google 的 Custom Search JSON API,以及其他类似文档,以增强您对速率限制的了解,并尝试使用不同的时间限制自己进行实验。

此外,您还可以从我们的博客:

祝您编程愉快!

author

Shreyas Patil

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的创意设计师,专注于通过传统和创新营销渠道打造一致的企业形象。他擅长将艺术愿景与战略营销相融合,创造具有影响力的品牌叙事。

评论

暂无评论。发表第一条评论吧。