英文:
ActiveMQ & Java - delays when between publish & consume
问题
我有一个服务器,在这个服务器上我有一个发布者,它将消息发送到一个单独的队列。从这个队列中读取消息,我有5个消费者,每个消费者都在自己的JVM上运行。想法是,发布者的消息应该尽快被任何空闲的消费者消费掉。有时候这5个消费者都是空闲的,然后ActiveMQ可能会选择其中一个来接收/出队消息,是这样吗?
所有的消息都是非持久化的。我基本上使用的是开箱即用的ActiveMQ,只有一个队列,并且没有对任何配置文件进行过任何调整。我也没有使用事务。
发布者在返回后会记录下毫秒级的时间:
public void sendMessage(String text) {
TextMessage message = null;
try {
message = session.createTextMessage(text);
producer.send(message);
System.out.println("刚刚完成消息发送 " + System.currentTimeMillis());
} catch (JMSException e) {
e.printStackTrace();
}
}
每个消费者(在自己的JVM上运行)会在队列上监听2分钟的突发时间:
Message message = consumer.receive(120000);
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
text = textMessage.getText();
System.out.println("收到消息 " + System.currentTimeMillis());
}
通常情况下,消费者会在与"刚刚完成消息发送"的时间戳几乎相同的毫秒数内记录"收到消息",这很完美。但是有时候,即使所有的消费者都是空闲的,发布和消费之间会有大约15毫秒的不可解释的延迟。考虑到所有的进程都在同一台服务器上运行,而且延迟绝对至关重要,我对这种延迟感到很困扰。
- 当从1个队列运行多个消费者时,是否应该期望出现这种情况,或者这与问题无关?
- 我能做些什么来减少这种延迟?
提前感谢您提供的任何有用的建议。
英文:
I have one server, on which I have one publisher which sends messages to a single queue. Reading from this queue I have 5 consumers, each on its own JVM. The idea is that the publisher's messages should be consumed as soon as possible by whichever consumer(s) is free. Sometimes all 5 will be free and then ActiveMQ presumably chooses one to receive/dequeue the message (?).
All messages are non-persistent. I'm using ActiveMQ pretty much out the box with just 1 queue and zero tinkering to any config files. I'm also not using transactions.
The publisher logs the time in millseconds right after it's returned:
public void sendMessage(String text) {
TextMessage message = null;
try {
message = session.createTextMessage(text);
producer.send(message);
System.out.println("JUST FINISHED SENDING MESSAGE " + System.currentTimeMillis());
} catch (JMSException e) {
e.printStackTrace();
}
}
Each consumer (running its own JVM) is listening on that queue for bursts of 2 minutes at time:
Message message = consumer.receive(120000);
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
text = textMessage.getText();
System.out.println("MESSAGE RECEIVED " + System.currentTimeMillis());
}
Usually consumers will log "MESSAGE RECEIVED" at exactly the same time in milliseconds as the "JUST FINISHED SENDING MESSAGE", which is perfect. But sometimes there is an inexplicable delay of around 15 milliseconds between the publish and the consume, even when all consumers are sitting free. Given all processes are on the same server, and that latency is absolutely critical, I'm frustrated that there's sometimes this delay.
- Is this to be expected when running multiple consumers from 1 queue, or is that irrelevant?
- Is there anything I can do to mitigate the delay?
Thanks in advance for any useful advice.
答案1
得分: 4
由于与网络消费者和中央代理之间的交互,存在诸多导致短暂延迟的原因。无论是代理还是消费者的CPU调度,以及管理网络接口所需的工作,都可能导致小的中断。您可能还会看到JVM在消费者或代理上进行垃圾回收时会出现GC暂停,从而可能会延迟分发或消费。当然,线程间的信号传递也可能会因为与其他并行运行的任务相关的各种因素而导致短暂延迟。因此,除非您已经解决了所有其他可能存在的问题,否则在处理这些短暂暂停时可能不值得投入大量时间。
英文:
There are many reasons for short delays like this when dealing with network consumers and a central broker. The CPU scheduling of either the broker or the consumer along with work done managing the network interface could lead to small hiccups. You might also be seeing GC pauses as the JVM on the consumer or the broker cleans up which can delay dispatch or consumption. And of course inter-thread singaling can sometime have short delays depending on various things running alongside so these short pauses are really something I'd invest a ton of time in unless you get to the point where that is the last issue you need to solve out of all the other likely things you aren't dealing with yet.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论