我正在研究一个需要延迟PHP事件的在线PHP应用程序。 基本上我需要能够在初始命中URL后多次执行任意PHP代码x。 我需要相当精确地执行这些PHP事件,我也希望它具有相当的可扩展性。 我试图避免需要安排一个cron作业来每秒运行。 我正在研究Gearman,但它似乎没有提供任何安排事件的能力,据我所知,PHP并非真正意味着作为守护进程运行。
外部调用PHP(必须解析HTTP请求或通过CLI进行调用)有很多开销,以使这个想法适合我的需要。
我正在创建一个在线游戏,让玩家轮流变换时间限制。 我使用XMPP和BOSH来允许我向客户端发送消息,但我已经完成了所有工作。 现在我试图添加一个任意的事件,这个事件在客户端发挥作用后触发,让客户(以及其他玩家在游戏中)花费很长时间。 我不能在客户端使用定时触发器,因为这会被利用(因为客户端可以自己玩)。
这里有一个指向PHP事件循环库的链接,名为LooPHP。
要求
发布于 2018-03-13 07:48:52
Kendall提出的问题:
PHP非常友好。 许多用户正在为redis编写PHP库。 协议非常简单。 你可以用telnet进行调试;)。 举个例子,很快就会出现阻止弹出窗口的情况。
Redis是一个先进的键值存储。 它与memcached类似,但数据集不是易失性的,值可以是字符串,与memcached完全相同,也可以是列表,集合和有序集合。 所有这些数据类型都可以使用原子操作来操作,以推/拉元素,添加/移除元素,执行服务器端联合,交集,集合之间的差异等等。 Redis支持不同种类的排序功能。
我想出的(伪代码...):
processor.php:
<?php
######----processer.php
######You should do something like nohup php processor.php enough times for processors to run event.
#$key: should be unique, but should also be used by wakeup.php
while(true) {
$event = blpop($key); #One of the available blocking threads will wakeup and process event
process($event); #You should write process. This could take some time so this process could not be available
zrem($key1, $event); #Remove event after processing it. Added this later!!!!!!
}
client.php:
######----client.php
######The user/browser I guess should generate these events.
#$key1: should be unique.
#$millis: when event should run
#$event: just the event to work on.
if ("add event") {
zadd($key1, $millis, $event);
} else if ("delete event") {
zremove($key1, $event)
}
#Get event which has to be scheduled first
$first = zrange($key1, 0, 0);
if ($oldfirst <> $first) { #got different first event => notify wakeup.php.
lpush($key2, $first);
}
$oldfirst = $first;
wakeup.php:
####wakeup.php
#### 1 time do something like nohup php wakeup.php
#http://code.google.com/p/redis/wiki/IntroductionToRedisDataTypes => read sorted set part.
while(true) {
$first = zrange($key1, 0, 0);
$event = blpop($key2, $timeoutTillFirstEvent);
if ($event == nill) {
#Blockingqueue has timedout which means event should be run by 1 of blocking threads.
blpop($key2, $first);
}
}
我创造了一个Java程序你可以用它来解决你的问题。
参观GitHub下载页面下载JAR文件(包括所有依赖项)。
1. First `php -f scheduler.php`
2. Next `php -f receiver.php`
我创建了这些小片段,希望能够在维基理解如何使用我的程序。
一个快速的解决方案是使用谷歌的应用程序引擎任务队列,它有一个合理的免费配额。在那之后,你必须为你使用的东西付钱。
使用此模型,App Engine的任务队列API允许您将任务指定为HTTP请求(请求的内容作为其数据,并将请求的目标URL作为其代码参考)。以这种方式以编程方式引用捆绑的HTTP请求有时称为“Web钩子”。
重要的是,Task Queue API的离线特性允许您提前指定Web挂钩,而无需等待其实际执行。因此,应用程序可能会一次创建多个Web钩子,然后将它们交给App Engine;系统会在后台异步处理它们(通过“调用”HTTP请求)。这个Web钩子模型可以实现高效的并行处理--App Engine可以同时调用多个任务或Web钩子。
总而言之,Task Queue API允许开发人员通过将该工作分块为脱机Web钩子来异步执行后台工作。系统将代表应用程序调用这些Web挂钩,通过可能并行执行多个webhook来调度以获得最佳性能。这种基于HTTP标准的粒度工作单元模型使App Engine能够以适用于任何编程语言或Web应用程序框架的方式高效地执行后台处理。
发布于 2018-03-13 09:14:52
php脚本执行一个exec调用,以安排PHP脚本在需要时使用“at”命令运行
exec(“22:56/usr/bin/php myscript.php”);
AT在指定时间执行命令。
从手册页:
At允许相当复杂的时间规格,扩展了POSIX.2标准。它接受HH:MM形式的时间在一天中的特定时间运行一项工作。 (如果此时间已过,则假定为第二天。)也可以指定午夜,中午或下午茶时间(下午4点),并且可以在上午或下午晚间。还可以通过以可选年份的月份名称日期的形式给出日期,或者给出MMDDYY或MM / DD / YY或DD.MM.YY的格式的日期来说明工作将在哪一天运行。日期的规格必须遵循一天中的时间规格。你也可以给出像现在这样的时间+计算时间单位,其中时间单位可以是几分钟,几小时,几天或几周,你可以通过在今天后加上时间告诉今天工作,并明天开始工作通过在明天后缀时间。
此外,如果需要一秒的时间分辨率,请在一分钟的开始时间运行脚本,然后在n秒钟内休眠,直到需要执行。
发布于 2018-03-13 10:14:10
这看起来像是数据库中事件队列的完美场所。
让用户创建的事件(通过访问网页触发)创建一个条目到数据库中,其中包含要执行的操作说明以及应该发生的时间戳。守护进程(持久性应用程序或由CRON触发)会检查数据库中是否发生了应该发生的事件($ TriggerTime <= time()
)并且尚未标记为“已处理”。如果发现一个或多个这些事件,请执行该指令,最后在数据库中将事件标记为“已处理”或者直接删除该条目。
使用数据库来存储事件(而不是驻留在应用程序的RAM中)的好可以从崩溃中恢复而不会丢失数据,可以让一个以上的工作人员在单个事件中读取数据时间,你可以简单地修改事件。
此外,还有很多人将PHP用作服务器上的一般守护程序脚本语言等.Cron可以执行一个PHP脚本(并确认该“app”的实例已在运行),该脚本每隔一小时检查一次事件队列-经常。您可以在一分钟不活动后再使用一个小应用程序,然后由CRON重新启动。该应用程序可以按照选择的频率快速检查数据库(如1s)。通常Cron不能做比每分钟一次更快的计时事件。
https://stackoverflow.com/questions/-100007604
复制相似问题