首页 > 解决方案 > 在不让两个人访问的情况下在 PHP 中分配资源

问题描述

我有一个将给定资源分配给用户的系统。每天有成千上万的人访问该系统。

在包含这些资源记录的数据库表中,我们有一列让我们知道该资源是否已分配。

当一个 API 请求进来分配资源时,我们运行一个查询来查找一个未分配的资源。下一行代码是检查是否返回 false,以便我们可以显示错误。之后的下一行 if 将该资源锁定给该用户。我们在查找和分配之间最多讨论 1-2 毫秒。

我担心随着流量的增加,有可能不止一个用户返回相同的资源。我们有一个确定性算法,每次我们请求时都会返回相同的资源。

有没有一种好方法可以确保两个人不可能返回同一个实例?

我的底层系统是 Laravel 5.8,在 AWS 中运行。负载平衡(应用 ELB)、多个应用服务器、多个工作服务器。DB 是在 RDS 上运行的 Postgres。Redis 用于缓存和队列管理。

标签: phplaravelpostgresql

解决方案


对于您的情况,您将必须获得数据锁定;包含在数据库级别的事务中。@tadman 是对的。但是,这些提示可能只是您的高负载系统的起点,因为据我所知,您需要获取昂贵的表锁。

因此,您可能会遇到下一个限制:并发事务;在最坏的情况下导致死锁。您可以通过查看每分钟实际回答多少“分配请求”(您的 API 端点响应)来评估/估计这种风险。

如有必要,我会拆分问题:

  • 有一个非常快的“未分配资源堆栈”:分配具体资源,在写入时检查它是否仍然未分配/在池中;如果没有,请从“快速堆栈”中获取下一个(或明确地是最后一个)
  • 异步填充快速堆栈,使其池大小始终“足够”

推荐阅读