PHP 长轮询 - 应该“long”多长时间是?

发布于 2024-11-19 00:49:47 字数 389 浏览 3 评论 0原文

当在 PHP 中使用长轮询时,例如,

$start_time = time();
while ((time() - $start_time) < 30) {
if ($db->getNewStuff()->rows > 0) {
    $response = "new stuff!";
    break;
}
usleep(1000000);
}
echo $response;

您如何评估,您“轮询”“多长时间”?在这个例子中,我选择了 30 秒,因为……好吧,我什至不知道为什么。

使用更长的时间(几分钟或类似时间)的民意调查会产生什么影响?阿帕奇会崩溃吗?我的应用程序会出现延迟/卡住/性能下降吗?

此外:进程应该休眠多长时间?

When using long polling in PHP, e.g.

$start_time = time();
while ((time() - $start_time) < 30) {
if ($db->getNewStuff()->rows > 0) {
    $response = "new stuff!";
    break;
}
usleep(1000000);
}
echo $response;

How do you evaluate, how "long" you "poll"? In this example, I chose 30 seconds, because... well, I can't even tell why.

What are the impacts when using even longer polls, several minutes or alike? Will Apache crash? Will my application get laggy / stuck / decrease performance?

Furthermore: How long should the process usleep?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

初见你 2024-11-26 00:49:47

您的 PHP 脚本可能不会存在那么久,具体取决于时间限制。因此,请务必(重新)设置时间限制。否则,我认为增加时间不会有任何问题。

至于usleep应该持续多长时间,这个需要你自己衡量。较短的微睡眠会增加服务器负载,但会更快地找到结果。什么是合适的很大程度上取决于您的应用程序的其余部分和您的资源。您甚至可能希望根据服务器负载改变微睡眠时间(即,当服务器负载较高时使其睡眠时间更长)。

Your PHP script may not live that long, depending on the time limit. So, be sure to (re)set the time limit. Otherwise I don't see any problem increasing the times.

As for how long the usleep should be, that is something that you need to benchmark for yourself. Shorter microsleeps will increase the server load, but find results faster. What is appropriate is determined very much by the rest of your application and your resources. You may even want to vary the microsleep time according to the server load (i.e. make it sleep longer when server load is high).

书间行客 2024-11-26 00:49:47

您可以轻松地使可用的 apache 进程/workwer 饱和。
例如,如果 apache 配置如下:

StartServers       2
MinSpareServers    4
MaxSpareServers    8
ServerLimit        11
MaxClients         11
MaxRequestsPerChild  4000

您只能提供 11 个请求,您的站点将在最后 30 秒内无法访问。
如果您只是寻找概念证明,那么使用 apache 和 PHP 是可以的,但在真正的服务器上,您确实可以避免 PHP --> Apache 长轮询。

您需要使用类似于 comet 环境的可扩展解决方案

You can easy saturate the available apache process/workwer.
For instance if the apache is configured as show below:

StartServers       2
MinSpareServers    4
MaxSpareServers    8
ServerLimit        11
MaxClients         11
MaxRequestsPerChild  4000

You can just serve 11 request ad your site will be unreachable for at last 30 seconds.
If you are looking for just a proof of concept, it's ok to play with apache and PHP but on a real server you really avoid a PHP-->Apache long polling.

You need to use something likas a comet environment for a scalable solution

澜川若宁 2024-11-26 00:49:47

当调用 usleep() 时,php 不执行任何操作,直到睡眠到期。

一般来说,默认的最大脚本执行时间是30秒,但是sleep()和usleep()会持续更长的时间,因为技术上PHP在睡眠操作期间没有控制权。

从未尝试过超过几分钟 - 也从未遇到过任何问题。

如果事情很忙并且有很多线程进入休眠状态,那么您可能会用完线程来处理其他请求......

When usleep() is called php does nothing until the sleep expires.

Generally the default maximum script execution time is 30 seconds, but sleep() and usleep() will go on for longer because technically PHP does not have control during the sleep operation.

Have never tried any more than a few mins - and never had any issues.

Potentially if it's something busy and get lots of threads going to sleep - you could run out of threads to process other requests...

妞丶爷亲个 2024-11-26 00:49:47

什么是长轮询

您提供的代码不是长轮询。长轮询是指您允许客户端等待某些内容,并允许您的用户界面立即响应服务器上的事件。

客户端发出常规的 ajax 请求。您的服务器代码可能会等待,也可能会立即响应。

如果(还)没有什么可返回的,它只会使响应花费更长的时间来响应。如果发生某些等待的事件,它会立即发送响应。

客户端轮询您的 ajax 请求,该请求在发生某些事件之前不会响应,但当该事件发生时,它会立即响应。客户端应该立即转身并执行另一个长轮询请求。

防止错过事件

因此,您通常在长轮询协议中使用序列号。每个事件都分配有一个序列号,较新的事件比较旧的事件具有更高的序列号。如果您可以安排这一点,那么您可以将长轮询设为“获取自 id 以来的事件”请求。如果他们错过了一些事件,它会立即返回。如果他们给了你最新的序列号,那么就没有什么可返回的,所以不要返回任何响应,只是让它需要更长的时间。

如果在长轮询之间潜入了多个事件,您的轮询将返回多个事件记录。

这需要您的代码通过某种方式通知事件来通知正在等待发送响应的代码。您可以将其实现为键值存储的合理速率轮询、某种进程间通信或适合重复使用的轻量级通信。

由于 PHP 的进程模型,您的选择在某种程度上受到限制。在nodejs或其他单进程服务器架构中,您可以使用一个简单的响应数组来等待结果,并在新事件发生时调用它们,尊重每个响应的“since”参数。

经典示例

聊天客户端就是一个典型的示例。聊天页面上的所有人都坐在那里进行了长时间的民意调查,花了很长时间才得到回复。该页面工作正常,只是网络请求在后台花费了一些时间。

当有人键入消息时,他们会将其发布到服务器,并且该处理程序会插入一条带有下一个 id 的消息。所有长轮询都会注意到新记录大于它们正在查找的“since”值,并且它们将立即发送 id 大于“since”参数的所有记录的响应。本质上是在短时间内通知所有其他聊天参与者,而无需让他们自己不断检查新消息。

What long polling is

The code you presented isn't long polling. Long polling is when you allow clients to wait for something, and allows your user interface to respond instantly to events on the server.

The client makes a regular ajax request. Your server code might wait, or might respond immediately.

If there is nothing to return (yet), it simply makes the response take longer to respond. If and when some waited-for event occurs, it sends a response immediately.

The client polls your ajax request, which doesn't respond until some event occurs, but when that event occurs, it responds instantly. The client is expected to turn around and do another long poll request, right away.

Preventing missed events

For this reason, you usually use a sequence number in your long poll protocol. Each event is assigned a sequence number, and newer events have higher sequence numbers than older events. If you can arrange for that, then you can make the long poll be a "get events since id" request. If there are events they missed, it will return them instantly. If they gave you the latest sequence number, then there is nothing to return, so don't return any response, just make it take longer.

If multiple events sneak in between long polls, your poll will return multiple event records.

This requires some way for your code that notifies an event to notify the code that is waiting to send a response. You can implement that as a reasonable-rate poll of a key-value store, some sort of interprocess communication, or something suitably lightweight for repeated use.

Your options are somewhat limited in PHP, due to its process model. In nodejs or another single-process server architecture, you could use a simple array of responses awaiting results, and call them all, respecting each one's "since" parameter, when a new event occurs.

Classic example

A chat client is the classic example of this. All of the people on the chat page have a long poll sitting there taking long to get a response. The page working fine, just a network request taking time in the background.

When someone types a message, they post it to the server, and the handler for that inserts a message with the next id. All of the long polls will notice the new record is greater than the "since" value they are looking for, and they will immediately send a response for all records with an id greater than the "since" parameter. Essentially notifying all of the other chat participants within a short time, without making them constantly check for new messages themselves.

汐鸠 2024-11-26 00:49:47

您确实应该考虑使用 Node 和 Socket.io。 :)

You should really look into using Node and Socket.io. :)

撞了怀 2024-11-26 00:49:47

总响应间隔超过 20 秒将使您的应用程序容易出现浏览器超时。为了安全起见,请保持在 20 秒或以下。

Having a total response interval of 20+ seconds will make your application prone to browser timeouts. Keep it at, or below 20 seconds -- just to be on the safe side.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文