【问题标题】:Symfony and Heroku worker: can I use the database as communication mechanism between the front-end and the background worker?Symfony 和 Heroku worker:我可以使用数据库作为前端和后台 worker 之间的通信机制吗?
【发布时间】:2016-11-25 19:12:32
【问题描述】:

我需要一个Heroku's Worker 来执行一些后台任务。

现在,阅读文章PHP 中的worker 后台工作,我发现the architecture designed in the article makes use of RabbitMQ 是web dyno 和worker dyno 之间的消息传递系统。

但我不想使用 RabbitMQ,因为现阶段它真的太复杂了。

因此,作为web dynoworker dyno 之间的通信机制,我想使用以下两种选择之一:

  1. 简单的数据库(主要是我的最佳选择:P)
  2. AWS SQS(我可以使用,但数据库更适合我的需求)

现在,using RabbitMQ 提供的示例使用回调使脚本处于活动状态并不断接收队列中的新消息:

$callback = function($msg) use($app) {
    $app['monolog']->debug('New task received for censoring message: ' . $msg->body);

    try {
        // call the "censor" API and pass it the text to clean up
        $result = $app['guzzle']->get('censor', ['query' => ['corpus' => $msg->body]]);
        $result = json_decode($result->getBody());
        if($result) {
            $app['monolog']->debug('Censored message result is: ' . $result->censored_text);
            // store in Redis
            $app['predis']->lpush('opinions', $result->censored_text);
            // mark as delivered in RabbitMQ
            $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
        } else {
            $app['monolog']->warning('Failed to decode JSON, will retry later');
        }
    } catch(Exception $e) {
        $app['monolog']->warning('Failed to call API, will retry later');
    }
};

$channel->basic_qos(null, 1, null);
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);

// loop over incoming messages
while(count($channel->callbacks)) {
    $channel->wait();
}

我的问题是:如何在不使用 RabbitMQ 的情况下“模拟”$channel->wait() 命令?

换句话说,我怎样才能让worker dyno 能够从数据库或 AWS SQS 中读取队列,持续地开始处理出现在数据库或 AWS SQS 队列中的消息?

我是否应该使用使用 Heroku Scheduler 的计划作业来启动测功机?(不适用:请参阅 here 为什么)。

或者还有其他我没有考虑的流程?

或者,更多,也许创建一个基于前端应用程序的symfony command line app 是最终的解决方案?它会不停地运行吗?

【问题讨论】:

  • 我认为你必须使用 Symfony 命令行应用程序,你可以在 Heroku 中像 ruby​​ 脚本一样定义它:devcenter.heroku.com/articles/scheduler#defining-tasks
  • 为什么使用“AWS SQS 队列”?
  • 为什么不呢?无论如何,因为我已经在使用其他 AWS 服务...
  • 无论如何我已经在使用调度程序:这里的问题是我想要一个几乎实时监听的后台进程,就像提供的示例中的工作人员一样赫罗库。但问题是该示例使用了 RabbitMQ。
  • 监听数据库或向另一个服务发出请求?

标签: php heroku background-process


【解决方案1】:

如果您使用 Heroku PostgreSQL(例如),您可以让您的工作进程在 asynchronous notifications 上侦听,您可以通过创建适当的触发器从数据库中获取。

详情请见this nice post on Postgres Pub-Sub features

因此,您的网络测功机可以在数据库中插入或更新记录,这可以自动触发通知您的工作人员测功机。

您的工作人员 dyno 永远运行,并且只是在通知通道上侦听,处理它收到的任何消息。

如果您使用不同的数据库,它可能有也可能没有类似的功能。但这使用 Postgres 绝对是可行的(实际上非​​常容易)。

【讨论】:

  • 我认为使用数据库中的“TRIGGER”或“LISTEN”在另一个网络服务中进行查询不是一个好主意,甚至有可能......
  • 为了推进主题,这里有一个对我有用的帖子:stackoverflow.com/questions/23571924/…
  • 我也不喜欢使用由数据库处理的触发器的想法。无论如何,我正在使用 MySQL...
猜你喜欢
  • 2016-06-07
  • 2021-02-02
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 2018-08-22
相关资源
最近更新 更多