onMessage() 中的长问题:如何处理?我希望这个方法由线程调用

发布于 2024-10-31 07:08:26 字数 1194 浏览 1 评论 0原文

我在接收 JMS 消息时做了一些严重的处理,超时风险很高。

对我来说使用 JMS 的全部目的是允许异步完成这种计算。 (如果其中一个消费者阻塞,我不希望其他消费者阻塞,我也不希望我的生产者阻塞,永远)。 理想情况下,我还希望我的消费者能够在计算第一个消息时接收第二条消息

现在,我正在使用独特的javax.jms.Session 用于发送和使用我的消息。 我知道这是受孕错误。正如文档所述:

会话可以创建并服务多个消息生产者和消费者。

但是也 :

如果客户端希望让一个线程生成消息,而其他线程使用消息,则客户端应为其生成线程使用单独的会话。

解决方案可能是为生产者使用会话,为每个消费者使用不同的会话,但消费者仍然只能一次处理一条消息

据我了解, onMessage 方法是由 Jms Provider 调用的(在我的例子中是 ActiveMq )。任何配置都可以允许在多个线程中调用此调用吗?

也许这个问题反映了我对 JMS 应该如何使用/我的概念的理解中的主要缺陷。请随意讨论;)

谢谢!

编辑:

我的问题一句话:

  • 如果我有 2 个消费者,并且其中一个需要很长时间来处理 onMessge,则所有其他消费者都会阻塞。

今天做了什么:我正在使用java.util.concurent.Executor,但我不太喜欢这个解决方案。我在 Tomcat 应用程序服务器上下文中,并且已经使用了太多线程,我想将此责任委托给一组更强大的代码。 (例如:activeMq)

编辑2:

更多细节:

  • 我不使用事务会话

  • 我使用Auto_Acknoledge

I do some heavy traitement at reception of JMS message, with high risk of timeout.

whole point of using JMS for me is to allow this kind of computation to be done asynchronisely. ( I dont want my other consumer to block if one of them block, i dont want my producer to block, ever ). ideally, i also want my consumer to be able to receive second message during computation of first one

Right now, i'm using unique javax.jms.Session for sending, and consuming my message.
I'm aware it was conception mistake. As doc state :

session can create and service multiple message producers and consumers.

But also :

If client desires to have one thread produce messages while others consume them, client should use separate session for its producing thread.

solution could be to use session for producer, and different session for each consumer, but consumers will still be able to handle only one message at time

For my understanding onMessage method is called by Jms Provider ( ActiveMq in my case ). Could any configuration allow this call to be call in several thread ?

Maybe this question is reflect of major flaw in my understanding of how JMS should be use / my conception. Please fell free to discuss ;)

Thanks !

Edit :

my problem in one sentence :

  • if i have 2 consumer, and if one of them take long time to process onMessge, all other consumer will blocK.

What is done today : I'm using a java.util.concurent.Executor, but i'm not a big fan of this solution. I'm in a Tomcat application server context, and already using too much thread, i will like to delegate this responsability to a more robust bunch of code. ( Eg : activeMq )

Edit 2 :

More detail :

  • I dont use transactional session

  • I use Auto_Acknoledge

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你爱我像她 2024-11-07 07:08:26

您的描述很难理解,我不认为这是语言问题。我最好的理解是你的生产者正在阻塞,因为消费者需要很长时间来处理消息。如果为 true,这意味着您正在使用持久消息并在处理消息后进行显式确认。

如果是这种情况,两种可能的解决方案是:(1)确定您是否真的需要保证,如果不需要,则使用隐式确认和/或非持久消息,或者(2)可靠地将消息存储在消费者中,确认,然后处理消息。


根据您的编辑,简短的答案是“是的,您可以生成线程”。由于生产者并不关心消费者是否能够实际处理消息,因此您在处理消息的方式上有很大的灵活性。

我怀疑 ActiveMQ 有一些属性可以让您控制消息处理线程的数量。我没有广泛使用它(更喜欢 HornetQ),所以无法给出明确的答案。

然而,即使确实如此,我还是更喜欢使用 Java ThreadPoolExecutorService(我认为这就是它的名称;请参阅 java.util.concurrent)。主要原因是它提供了自己的内部工作队列。无论您为消息传递框架提供多少线程,您总是有可能有足够的工作来捆绑它们。使用 ExecutorService,您将继续接收消息并对其进行排队,直到内存耗尽(如果发生这种情况,则需要解决一些设计问题)。

Your description is a hard to follow, and I don't think it's a language issue. My best understanding is that your producer is blocking because the consumer takes a long time to process the message. If true, this implies that you're using durable messages and explicit acknowledgment after processing the message.

And if that's the case, the two possible solutions are: (1) decide whether you really need the guarantees and use implicit acknowledgment and/or non-durable messages if not, or (2) reliably store the message in the consumer, acknowledge, and then process the message.


Based on your edits, the short answer is "yes, you can spawn threads." Since the producer doesn't care whether the consumer is able to actually process the message, you have a lot of flexibility in how you handle it.

I suspect that ActiveMQ has some property that would allow you to control the number of message-processing threads. I haven't used it extensively (prefer HornetQ), so can't give a definitive answer.

However, even if it does, I'd prefer using a Java ThreadPoolExecutorService (I think that's the name of it; see java.util.concurrent). The main reason is that it provides its own internal work queue. No matter how many threads you give to the messaging framework, there's always the possibility that you'll have enough work to tie them up. With the ExecutorService, you will continue to receive and queue messages until you run out of memory (and if that happens, you have some design issues to resolve).

唔猫 2024-11-07 07:08:26

javax.jms.Session 及以下(MessageConsumer、MessageProducer )是单线程的。如果你想要多线程,你就需要多个会话。每个消费者一个会话。

每个消费者都是单线程的。但是,如果多个消费者是从多个会话创建的,那么 JMS 实现应该能够在多个消费者之间进行多线程消息传递。

javax.jms.Session and below (MessageConsumer, MessageProducer) are single-threaded. If you want any multithreading, you want multiple Sessions. One Session per consumer.

Each consumer will be single-threaded. But a JMS implementation should be able to multi-thread message deliver between multiple consumers if they're created from multiple sessions.

独享拥抱 2024-11-07 07:08:26

您应该简单地将繁重的工作简化为可以在一笔交易中处理的流程。

我无法帮助你,因为你没有提到这个特质是什么。

You should simply cut down your heavy traitement into a process that can be handled into one transaction.

I can not help you since you don't mention what this traitement is about.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文