【问题标题】:Implementation of order management service using Celey+RabbitMQ+Redis使用 Celey+RabbitMQ+Redis 实现订单管理服务
【发布时间】:2021-03-17 07:00:50
【问题描述】:

我已经使用zipstream 实现了将一些文件即时打包到.zip 文件中的功能,因此响应格式为mimetype='application/zip' 使用Flask。现在我想实现提交订单的服务(即生成.zip文件的任务),跟踪订单状态(例如STARTEDSUCCESSFAILURE),撤销订单(即取消生成@987654330的任务) @文件或删除生成的.zip文件),并为当前用户下载订单(即.zip文件)。我计划使用 CeleryRabbitMQ 作为消息代理,Redis 作为结果后端。

问题来了。仅 Redis 作为结果后端就足够了吗?因为用户订单的跟踪状态似乎涉及user = ... 之类的查询,而不是通过task id

支持AsyncResult 查询

更新: 感谢@Tomáš Linhart。我使用 celery 的signal handler mechanism 遵循将结果存储在 MongoDB 中的扩展方式。这是与我创建的任务相关的代码的 sn-p。我创建task_trackercelery_cli 实例的方式与@Tomáš Linhart 的answer 中的trackerapp 相同。

# Import task_tracker and celery_cli here
...

@task_tracker.track
@celery_cli.task(name='pack-up-tif')
def async_pack_up_tif(**kwargs):
    # Some processing here
    ...

def pack_up_tif(msg):
    result = async_pack_up_tif.delay(**msg)
    return result

但我还有一个问题。调用delay方法时如何拦截任务ID?因为当task_success 信号被触发时,我需要通过find_one_and_update 将该信息存储在MongoDB 集合中。

【问题讨论】:

  • 看看我对类似问题的回答 - stackoverflow.com/a/60300906/5832540。对于与我类似的用例,简单的结果后端是不够的,因为您需要存储 Celery 不知道的属性(例如用户 ID、订单 ID 等)
  • 谢谢@TomášLinhart。你的帖子对我帮助很大:)。
  • @TomášLinhart 我听从了你的回答,但仍然遇到问题,我已经更新了这篇文章。你能提供更多解释吗?谢谢。
  • 我发布了一个答案,应该会给你一个提示。

标签: python redis rabbitmq celery


【解决方案1】:

详细说明我发布的评论并回答您更新的问题。确定从哪里收集您想在每个信号中跟踪的各种数据有点复杂。一些信号为您提供任务本身,一些信号为您提供任务请求。

我以 task_success 信号的处理程序结束:

def _on_task_success(self, sender, result, **other_kwargs):
    if sender.name not in self.tasks:
        return

    collection = self.mongo \
        .get_database(self.config['mongodb']['database']) \
        .get_collection(self.config['mongodb']['collection'])
    collection.find_one_and_update(
        {'_id': sender.request.id},
        {
            '$setOnInsert': {
                'name': sender.name,
                'args': sender.request.args,
                'kwargs': sender.request.kwargs
            },
            '$set': {
                'status': states.SUCCESS,
                'date_done': datetime.datetime.utcnow(),
                'retries': sender.request.retries,
                'group_id': sender.request.group,
                'chord_id': sender.request.chord,
                'root_id': sender.request.root_id,
                'parent_id': sender.request.parent_id,
                'result': result
            },
            '$push': {
                'status_history': {
                    'date': datetime.datetime.utcnow(),
                    'status': states.SUCCESS
                }
            }
        },
        upsert=True,
        return_document=ReturnDocument.AFTER)

【讨论】:

  • 谢谢。不久前,我也从这里的answer 找到了关于使用sender.request.id 检索任务ID 的解决方案。我发现celery.uuid 可以应用于delay(..., task_id=uuid())。所以我现在可以关闭这个问题了。无论如何感谢您的耐心:)
猜你喜欢
  • 2016-03-13
  • 2019-01-08
  • 2010-10-29
  • 1970-01-01
  • 2013-06-30
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多