如何仅减慢当前请求的速度? sleep() 没有按预期工作

Posted

技术标签:

【中文标题】如何仅减慢当前请求的速度? sleep() 没有按预期工作【英文标题】:How to slow down only the current request? sleep() doesn't work as expected 【发布时间】:2021-06-12 04:31:07 【问题描述】:

有时我的应用程序需要等待一些东西。例如,在缓存的情况下:如果在缓存中找不到对象,则脚本在其键下设置一个特殊值,表示当前正在计算其值,并在完成后将其写入。如果在计算时另一个客户端请求相同的对象,则脚本不会重新计算它,而只会等待第一个。当然,这是一个简化的解释。我不知道如何正确地做到这一点,但这种行为在我看来是非常合乎逻辑的。

在测试一个完全不同的东西的过程中,今天我遇到了一个问题。

<?php
echo time() . "\n";
sleep(10); // usleep() has the same effect
echo time() . "\n";

同一秒,我在浏览器中的两个选项卡中打开此页面,并希望看到相同的数字,但是……稍后打开的选项卡在除了它的延迟,出于某种原因,它正在等待第一个选项卡延迟(蹩脚的措辞,但你理解我),所以我看到这样的东西:1615749037 16157490471615749047 1615749057。如果您添加更多选项卡,则下一个选项卡将等待所有以前的选项卡。

它打破了我的大脑。这根本不是我想象中的样子,多年来一直处于这种错觉之中。我目前无法找到有关此的任何信息。首先,我对如何达到预期的结果感兴趣。为什么 sleep() 会这样,我似乎开始猜测,但如果你分享一些信息,我会很高兴。谢谢!

UPD。以防万一,我检查了这个:如果我添加header('Cache-Control: no-cache, no-store, must-revalidate'),那么对我来说没有任何改变。但是如果我从不同的浏览器打开标签,那就没有问题了。

【问题讨论】:

您可以在URL中添加一个随机查询参数,该现象应该会消失,因为浏览器认为请求的是两个不同的页面。 @KIKOSoftware,它奏效了。但是对于相同的地址,即使禁用缓存也不起作用(请参阅更新的帖子)。也就是说,在特定客户端的特定浏览器中,对已加载页面的请求的阻止是内置的吗?那么直到什么时候请求被阻塞?直到收到第一个字节?如果是这样,那么一切似乎都很好。但我有一个极其模棱两可的印象。 我认为这背后的逻辑是:如果第一次还没有成功,为什么还要尝试第二次或第三次检索页面。因为所有浏览器都知道该页面甚至可能不存在或无法正确下载。 @KIKOSoftware,这确实有一些逻辑,看起来这就是它的工作原理——浏览器似乎正在创建一个请求队列。我最初认为这是服务器端的某种进程分叉。我现在想不出任何负面影响,如果这样的话……当然,除了这些问题的出现。 【参考方案1】:

从阅读中我看到两个问题

1。如何在处理第一个请求时阻止第二个请求?

为此,我的答案是锁。对于 PHP,我特别推荐Symfony lock component。您将使两个请求都获得一个锁,并且只有在完成并生成缓存后才释放它。

2。为什么同时触发的 2 个请求会互相等待?

我的猜测是您的浏览器有一些内置的队列/缓存或诸如此类的东西。您可以通过在不同的浏览器中打开相同的页面来查看是否会产生不同的结果来规避这种情况。

【讨论】:

以上是关于如何仅减慢当前请求的速度? sleep() 没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

减慢每秒仅进行一定次数迭代的循环[重复]

程序在 Thread.sleep() 和 Timer 期间冻结

如何减慢 MySQL 转储速度以免影响服务器上的当前负载?

图像显着减慢 Rspec 请求规范

如何延迟/减慢 UIScrollView 平移速度

如何减慢postgresql服务器的速度?