2014-04-11 88 views
2

我需要持续出队来自Oracle队列的消息。关于Oracle AQ出队方法的建议

据我所知,我们可以通过两种方式消除消息,无论是通过异步自动通知方法,还是通过手动轮询过程,一次可以让一条消息出队。

我不能去异步通知功能,因为它收到的消息的数量可能会在高峰时间5分钟内达到1000和 我不想通过在后台产生多个回调过程来重载数据库。

通过手动轮询过程,我可以创建一个运行24 * 7的一次性调度程序作业,调用一个存储过程,在WAIT模式(侦听消息的类型)中循环消息。 这种方法的问题在于:1)调度程序作业连续运行并占用一个永久性作业槽 2)存储过程因为在等待消息的循环中运行而不会退出。

是否有任何替代/更好的解决方案,我不需要有一个工作/程序不断寻找消息?

我可以使用自动通知方法获取第一条消息的通知,取消订阅订阅者和进一步退出邮件,并且在没有更多消息时再次订阅队列吗?这是一个安全的方法,我会失去订阅和取消订阅之间的任何消息吗? 顺便说一句,我们使用Oracle 10gR2数据库,所以我不能使用PURGE ON NOTIFICATION选项。

欣赏您的专家解决方案!

回答

3

你说得对,对大容量队列使用自动通知不是一个好主意。

在一个客户我已经看到它运行24 * 7的一次性调度工作,似乎工作相当不错,他们可以排队一个特殊的“STOP”消息(进入队列的顶部)它侦听并停止处理消息。

但是,通常我会倾向于定期运行的工作(例如,每分钟一次,或适合您的任何粒度),从而将所有邮件出列。我会根据您在1分钟内预计的最大消息数量,将出列列表放入循环计数器和“最大消息”限制器的循环中。该作业将继续处理消息,直到(a)队列中没有更多消息,或(b)达到最大限制。

然后,您可以根据您希望在入队和出队之间看到的最大延迟来设置作业的计划。例如。如果消息在5分钟内未得到处理并不重要,则可以将该作业设置为每5分钟运行一次。

最大限制需要相当高的数字 - 例如10倍或100倍的预期最大数量 - 否则高峰可能会淹没您的队列,并且可能无法跟上。最大限度的想法是确保工作从不永远运行。这应该给ops足够的时间来检测队列中的问题(例如,如果某些流氓进程正在用伪造的消息淹没队列)。