调用外部API一次并缓存它


Calling external API once and cache it

我使用第三方API通过curl调用获取飞行数据。在我调用curl之后,我解析数据并将其插入到数据库中进行缓存。(API调用不免费)

每当多个用户在同一时间对一个航班发出相同的请求时,它会多次调用外部API,因为curl调用需要一些时间来解析数据,然后插入到数据库中。因此,所有请求都检查数据库,意识到它不在数据库中,并开始调用外部API。完成后,它意识到自己已经有了飞行数据,并停止进行数据库插入调用。

如何使用最佳实践防止这种情况发生?

    $flightnum = $_POST['flightnum'];
    if (isFlightInDB($flightnum))
        return json_encode (getFlightFromDb ($flightnum));
    else {
        $flight = callFlightApiAndCache($flightnum);
        return json_encode($flight);
    }

这里的简单工作流程是记住API上的请求已经发出。如果您使用Node.js,这将非常简单,因为Node.js是一个单一的应用程序,所有请求都将在该单一实例上运行,因此您可以有一个数组,在其中存储当前执行的所有API请求,并实现一些逻辑来等待结果、从数据库读取或执行API调用。

主要问题是查询将由PHP在单独的服务器线程中执行,并且将查询存储在数据库或本地文件中的速度太慢,无法保证不会多次执行API调用。

然而,PHP中有一个API,它允许您在PHP执行线程之间共享一个数组。查看shm_put_var()/shm_get_var(。想法是这样的:

  • 您从客户端获得查询
  • 使用shmget_var()获得共享数组
  • 如果API查询尚未存在,则立即存储该查询以阻止进一步的调用。
    • 如果已经存在:要么等待DB条目出现,要么返回DB条目,删除共享数组记录->然后退出
  • 检查DB是否有条目:返回DB条目,删除共享数组记录->然后退出
  • 执行API调用,并将结果存储在DB中
  • 删除共享数组记录
  • 出口