许多PHP进程同时运行
要求 我有一个web应用程序,它允许用户安排一些社交媒体任务,比如在Facebook或Twitter上发帖 每个用户都可以告诉应用程序在任何时候(14:00、15:11、17:54…)在其社交媒体帐户上发布 除此之外,我还需要每天为每个用户完成其他任务,比如获取他们的追随者/朋友,或者在Twitter上释放他们的追随者/朋友 形势 到目前为止,每个任务都有一个文件(post.php、getFollowers.php、analytics.php…)。例如: post.php 我为这个脚本创建了一个cron作业,它每分钟检查是否必须发布一些帖子。让我们假设我们运行脚本,它发现三个用户在这个时候想要推特,它将使用foreach循环迭代用户,并在每个帐户中发布 …其他脚本也执行相同的操作:让每个想做某事的用户都参与进来,创建一个队列并进行迭代 问题许多PHP进程同时运行,php,cron,Php,Cron,要求 我有一个web应用程序,它允许用户安排一些社交媒体任务,比如在Facebook或Twitter上发帖 每个用户都可以告诉应用程序在任何时候(14:00、15:11、17:54…)在其社交媒体帐户上发布 除此之外,我还需要每天为每个用户完成其他任务,比如获取他们的追随者/朋友,或者在Twitter上释放他们的追随者/朋友 形势 到目前为止,每个任务都有一个文件(post.php、getFollowers.php、analytics.php…)。例如: post.php 我为这个脚本创建了一个
提前感谢。使用队列和工作系统 队列,例如:Amazon SQS:
诀窍是,您有一个队列,然后有尽可能多的工作进程/服务器,以防止队列持续增长。使用受管理的分布式计划任务服务,如AWS Elastic Beanstalk或 使用AWS EB,您将在项目中包含一个
cron.yaml
文件,其中包含一个配置,例如:
version: 1
cron:
- name: "post"
url: "/post"
schedule: "* * * * *"
这将触发对http://localhost/post
每分钟
我还建议计划任务本身不要发送帖子,而是触发其他多个任务来发送帖子。使用AWS EB,您可以使用:
这将触发对工作层配置URL的POST请求(即http://localhost/worker
)用于正文中包含JSON编码数据的每条消息
这种方法允许您更好地根据同时发送的帖子数量进行缩放。这不会有帮助
exec()
阻塞,直到执行的任何操作完成。您必须将该作业放在后台,例如,exec('somejob&')
,这会引发一系列其他问题。@MarcB谢谢Marc。我不知道。有什么建议吗?你的架构是什么样的?你有工人阶层吗?这可能会引起兴趣。可能值得研究AWS或其他云服务,以便在不担心服务器的情况下卸载大量进程performance@FrancisEytanDortort我在Hostgator上有一个简单的共享服务器。有趣的文章。但是他们怎么能用一个脚本按时发布每个用户的帖子呢?谢谢你的回答。所以对于多个任务,我将收到一个使用AWS SDK的文件请求,它将处理post信息,并在队列中安排消息。然后该队列将及时向我的服务器发送一个包含信息的请求。我理解得好吗?是的。例如,计划任务将查找下一分钟要发布的帖子,然后在队列中为每个帖子创建一条延迟60秒的消息。在给定的延迟之后,每条消息将触发自己的http请求。您可以将延迟时间增加到15分钟。具有长延迟的优点是,您可以使用队列大小触发工作实例数量的增加。谢谢Francis,很好的解释。我得雇人,不是吗?您知道我是否可以在Hostgator共享服务器中使用cron.yaml吗?。我想如果某个用户删除了一篇文章,我就可以删除该消息了。再次感谢。我的解释是用于AWS弹性豆茎。这意味着,至少工作层必须托管在AWS上。(顺便说一句,有些资源是第一年的。)你可以阅读这项服务,有一个和。谢谢你的回答。以这种方式,我将在AmazonSQS上安排任务,它将在我的服务器上调用workers进程,为每个用户完成这项工作。我明白吗?几乎,你需要启动工人,他们要求排队工作。好处是你可以根据需要启动任意多个,并随时停止它们。真正的“多云”解决方案是根据任何给定时间的需求自动向上/向下旋转工人进程/服务器。
use Aws\Common\Aws;
$aws = Aws::factory('/path/to/my_config.json');
$client = $aws->get('Sqs');
$client->sendMessage(array(
'QueueUrl' => $queueUrl,
'MessageBody' => json_encode($post),
'DelaySeconds' => $delay,
));