许多 PHP 同时处理 运行

Lots of PHP processes running at the same time

要求

我有一个网络应用程序,允许用户安排一些社交媒体任务,例如在 Facebook 或 Twitter 上 posting。

每个用户都可以随时让应用程序在他的社交媒体帐户上发布(14:00、15:11、17:54...)。

除此之外,我还需要每天为每个用户完成其他任务,例如获取他们的 followers/friends 或在 Twitter 上取消关注他们的人。

情况

到目前为止,我已经为每个任务创建了一个文件(post.php、getFollowers.php、analytics.php...)。例如:

post.php

我为此脚本创建了一个 cron 作业,它每分钟检查是否必须发布某些 post。假设我们 运行 脚本,它找到了三个想要发推文的用户,它将使用 foreach 循环迭代用户,并在每个帐户中 post。

...其他脚本做同样的事情:获取每个想要做某事的用户,创建一个队列并迭代它。

问题

  1. 发布任务需要按时完成。
  2. 像获取关注者这样的长期任务每天需要 运行ning。

(1) 在 Twitter 和 Facebook 上发帖需要 30-40 秒,所以如果有五个用户想在 14:00 post,那么 3、4 和 5 就晚了。

(2) 获得一个用户的一些关注者需要 40-60 秒,因此如果有 1000 个用户,脚本将花费 11-16 小时,这绝对是不可扩展的。我应该能够在 2-3 小时内完成此任务。

解决方法?

我认为我可以通过分离用户任务并为每个用户执行一个流程来解决这两个问题。

这是一个正确且可扩展的解决方案吗?您将如何以可扩展的方式解决这些问题?

提前致谢。

使用队列和工作者系统。

队列,例如:Amazon SQS:

  1. 用户安排事情在 X 时间发生。
  2. cron 运行 会定期查找需要 运行 的作业。
  3. cron 脚本将作业弹出到队列中。

工人:

  1. 向队列询问作业
  2. 做这份工作
  3. 转到 1

诀窍是你有一个队列,然后有尽可能多的工作人员 processes/servers 来防止队列持续增长。

使用托管的分布式计划任务服务,例如 AWS Elastic Beanstalk Worker Tier or IronWorker

使用 AWS EB,您可以在项目中包含一个 cron.yaml 文件,其中包含如下配置:

version: 1
cron:
 - name: "post"
   url: "/post"
   schedule: "* * * * *"

这将每分钟触发一个 POST 请求 http://localhost/post

我还建议计划任务本身 发送帖子,而是触发其他多个任务来发送帖子。使用 AWS EB,您可以使用 AWS SDK for PHP:

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,
));

对于工作层(即 http://localhost/worker)中包含 JSON 编码数据的每条消息,这将触发对您配置的 URL 的 POST 请求正文。

这种方法可以让您更好地扩展同时发送的帖子数量。