首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >可伸缩的、延迟的PHP处理是什么?

可伸缩的、延迟的PHP处理是什么?
EN

Stack Overflow用户
提问于 2018-03-13 07:17:49
回答 10查看 0关注 0票数 0

我正在研究一个需要延迟PHP事件的在线PHP应用程序。 基本上我需要能够在初始命中URL后多次执行任意PHP代码x。 我需要相当精确地执行这些PHP事件,我也希望它具有相当的可扩展性。 我试图避免需要安排一个cron作业来每秒运行。 我正在研究Gearman,但它似乎没有提供任何安排事件的能力,据我所知,PHP并非真正意味着作为守护进程运行。

外部调用PHP(必须解析HTTP请求或通过CLI进行调用)有很多开销,以使这个想法适合我的需要。

我正在创建一个在线游戏,让玩家轮流变换时间限制。 我使用XMPP和BOSH来允许我向客户端发送消息,但我已经完成了所有工作。 现在我试图添加一个任意的事件,这个事件在客户端发挥作用后触发,让客户(以及其他玩家在游戏中)花费很长时间。 我不能在客户端使用定时触发器,因为这会被利用(因为客户端可以自己玩)。

这里有一个指向PHP事件循环库的链接,名为LooPHP

要求

  • 在延迟时间(从秒到天)调用(最好是本地的)PHP
  • 任意处理事件的创建/更新/删除(我期待大量取消的呼叫)。
  • 处理计划中的高负载事件(每台服务器每秒100到1000次)
  • 调用应该在预定时间的三以内
  • 此时,我不愿意将代码库重写为另一种语言。
EN

回答 10

Stack Overflow用户

发布于 2018-03-13 07:48:52

PHP/Redis解决方案

Kendall提出的问题:

  • redis的稳定性如何:Redis非常稳定。 开发人员真的写了一些干净的C代码。 你应该在github上检查它。 也有很多大网站使用redis。 例如github.They他们有一个非常有趣的博客文章,他们如何使github快速。 superfeedr也使用redis。 有更多的大公司正在使用redis。
  • PHP对redis有多友好:

PHP非常友好。 许多用户正在为redis编写PHP库。 协议非常简单。 你可以用telnet进行调试;)。 举个例子,很快就会出现阻止弹出窗口的情况。

  • 如何删除事件:我觉得你应该用ZRemCommand...

Redis是一个先进的键值存储。 它与memcached类似,但数据集不是易失性的,值可以是字符串,与memcached完全相同,也可以是列表,集合和有序集合。 所有这些数据类型都可以使用原子操作来操作,以推/拉元素,添加/移除元素,执行服务器端联合,交集,集合之间的差异等等。 Redis支持不同种类的排序功能。

我想出的(伪代码...):

processor.php:

代码语言:txt
复制
<?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:

代码语言:txt
复制
######----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:

代码语言:txt
复制
####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. 安装* java -jar schedule-broadcaster-1.0-SNAPSHOT-jar-with-dependencies-1277709762.jar
  2. 运行简单的PHP片段
代码语言:txt
复制
1. First `php -f scheduler.php`
2. Next `php -f receiver.php`
  1. 问题

我创建了这些小片段,希望能够在维基理解如何使用我的程序。

应用程序引擎的TaskQueue

一个快速的解决方案是使用谷歌的应用程序引擎任务队列,它有一个合理的免费配额。在那之后,你必须为你使用的东西付钱。

使用此模型,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应用程序框架的方式高效地执行后台处理。

票数 0
EN

Stack Overflow用户

发布于 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秒钟内休眠,直到需要执行。

票数 0
EN

Stack Overflow用户

发布于 2018-03-13 10:14:10

这看起来像是数据库中事件队列的完美场所。

让用户创建的事件(通过访问网页触发)创建一个条目到数据库中,其中包含要执行的操作说明以及应该发生的时间戳。守护进程(持久性应用程序或由CRON触发)会检查数据库中是否发生了应该发生的事件($ TriggerTime <= time())并且尚未标记为“已处理”。如果发现一个或多个这些事件,请执行该指令,最后在数据库中将事件标记为“已处理”或者直接删除该条目。

使用数据库来存储事件(而不是驻留在应用程序的RAM中)的好可以从崩溃中恢复而不会丢失数据,可以让一个以上的工作人员在单个事件中读取数据时间,你可以简单地修改事件。

此外,还有很多人将PHP用作服务器上的一般守护程序脚本语言等.Cron可以执行一个PHP脚本(并确认该“app”的实例已在运行),该脚本每隔一小时检查一次事件队列-经常。您可以在一分钟不活动后再使用一个小应用程序,然后由CRON重新启动。该应用程序可以按照选择的频率快速检查数据库(如1s)。通常Cron不能做比每分钟一次更快的计时事件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档