【问题标题】:Grails non time based queuingGrails 非基于时间的队列
【发布时间】:2012-03-02 06:39:57
【问题描述】:

我需要处理上传的文件,这可能需要 1 秒或 10 分钟。目前我的解决方案是使用 30 秒的计时器进行石英作业,然后在遇到时处理和任意作业。这有几个问题。

第一:如果作业将花费不到几秒钟,那么让作业队列等待 30 秒是浪费的。

二:如果队列中只有一个很长的工作,它可以尝试做两次。

我想要的是一个永恒的队列。添加内容后,如果有空闲工作人员,则会立即启动。有解决方案吗?我在看 jesque,但我不知道它是否可以做到这一点。

【问题讨论】:

  • Jesque 绝对可以做到这一点。这是消息队列背后的基本思想(与 Quartz 之类的作业调度程序相反,后者实际上不是队列)

标签: grails queue worker


【解决方案1】:

您正在寻找的是一个基本的消息队列。有很多选择,但我最喜欢 Grails 的是 RabbitMQ。它的 Grails 插件非常好,根据我的经验,它表现良好。

一般来说,消息队列允许您让 N 个生产者(创建作业的事物)将工作消息添加到队列中,然后 M 个消费者从队列中拉出作业并处理它们。当一个工作者完成它的工作时,它只是询问下一个要处理的作业的队列,如果没有,它只是等待队列给它做点什么。队列还跟踪消息处理的成功/失败(你可以控制它),这样你就不会t 向多个工人提供相同的信息。

这具有不依赖轮询的优点(因此您可以在有事情进入时立即开始处理)并且它的可扩展性也更强。您可以根据需要向上或向下扩展您的生产者和消费者,将输入与输出分离,以便您可以应对流量高峰,然后在您拥有可用资源(工作人员)时通过它。

【讨论】:

    【解决方案2】:

    要解决问题,只需每 5 秒(或 3 秒或 1 秒)检查一次新上传的文件。如果检查上传文件的速度很快,那么您没有理由不能经常运行它。

    对于问题二,您只需要在开始处理文件时进行记录,以确保它不会被拾取两次。您可以在数据库中创建一个表,或者将信息存储在内存中的某个位置。

    【讨论】:

    • 轮询不能很好地扩展,将数据库添加到循环中只会产生额外的资源争用。尤其是当应用程序向更实时的处理方向发展时,轮询很快就会崩溃。
    • 我的问题是我必须对第二个标志进行各种检查以解决处理挂起的情况。
    • @Mikey - 不用担心。但除非我遗漏了什么,否则即使您使用队列来安排它们,您仍然需要有代码来处理挂起的作业。
    • @Mikey,大多数消息队列都有可配置的 ack/nack 超时策略,如果它没有很快得到消息已成功处理的指示,它将自动将消息放回队列中。还有坏消息的情况,但这与挂起的消息不同。
    猜你喜欢
    • 2016-08-26
    • 2018-11-14
    • 2020-11-18
    • 2021-09-12
    • 1970-01-01
    • 2011-06-16
    • 2020-01-29
    • 2015-10-07
    • 1970-01-01
    相关资源
    最近更新 更多