我正在用Spring JMS
和ActiveMQ
到JNDI
/Tomcat
实现一个简单的演示。整个目的是让一个发送者和多个接收者,但队列中的消息必须同步操作,这意味着无论接收者有多少,所有的消息都应该按原始发送顺序处理。Spring JMS和ActiveMQ的同步问题
这是我做过什么
创建弹簧的应用程序,可以通过一个队列通过的ActiveMQ/Tomcat的/ JNDI发送和接收JMS消息。我把
@Transactional
改为onMessage()
方法(假设可以在JPA中工作,但可能不在这个例子中)。 sender方法使用@Scheule进行注释,并且每5秒运行一次并向队列发送10条消息。有一个全球计数器来计算正在发送的总邮件。部署此应用程序的三个实例,其中一个同时打开发送者和接收者,另外两个仅激活接收者。那么所有三个接收器都会将消息写入相同的
text file
(作为小型数据库使用),以便每个接收器在写入后都会关闭文件。我没有更改任何同步设置为ActiveMQ和Spring JmsTemplate,默认情况下以同步方式工作。
,这里是我
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(0)=messageBody1}
Mon Nov 24 13:57:00 EST 2014 Receiver 0 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(1)=messageBody2}
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(2)=messageBody3}
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(3)=messageBody4}
Mon Nov 24 13:57:00 EST 2014 Receiver 0 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(4)=messageBody5}
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(5)=messageBody6}
Mon Nov 24 13:57:00 EST 2014 Receiver 0 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(6)=messageBody7}
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(7)=messageBody8}
Mon Nov 24 13:57:00 EST 2014 Receiver 0 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(8)=messageBody9}
Mon Nov 24 13:57:00 EST 2014 Receiver 1 {from Sender agent..message_aj9gg95q1kmb77i8506bcn3dpp(9)=messageBody10}
Mon Nov 24 13:57:05 EST 2014 Receiver 1 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(0)=messageBody11}
Mon Nov 24 13:57:05 EST 2014 Receiver 0 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(1)=messageBody12}
Mon Nov 24 13:57:05 EST 2014 Receiver 0 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(2)=messageBody13}
Mon Nov 24 13:57:05 EST 2014 Receiver 1 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(3)=messageBody14}
Mon Nov 24 13:57:05 EST 2014 Receiver 0 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(4)=messageBody15}
Mon Nov 24 13:57:05 EST 2014 Receiver 1 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(5)=messageBody16}
Mon Nov 24 13:57:05 EST 2014 Receiver 1 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(6)=messageBody17}
Mon Nov 24 13:57:05 EST 2014 Receiver 1 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(8)=messageBody19} ----- oops
Mon Nov 24 13:57:05 EST 2014 Receiver 2 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(7)=messageBody18} ----- oops
Mon Nov 24 13:57:05 EST 2014 Receiver 0 {from Sender agent..message_n7ofp65ioqcfhdl63cjg76e4fb(9)=messageBody20}
距离消息体18和19(请向右滚动)他们打破了同步(消息18消息前,应提供明显的结果19)。我想知道它是否仅仅是ActiveMQ的一些随机案例,或者它可能是一些设置的潜在问题,或者可能是写入文本文件,所以如果它在真实数据库中,那么@Transactional可以保证同步
谢谢。没有定单的竞争者可以在竞争对手中随机选择消息,这是可以的,但是在这种情况下,消息的输出至少应该与队列中最初的消息相同。我确定随机出现接收者,但请检查消息18和消息19的顺序是否错误。对不起,我应该在门票中突出显示它。 – Dreamer 2014-11-25 02:15:27
你的测试没有提到生产者。它只是表明receiver2收到了消息18,receiver1收到了消息19 __at,并且接收方1碰巧赢得了在文件_中记录接收的竞赛。单个消费者的消息接收将按顺序进行,但并不保证消费者的下游处理将以任何顺序进行。所以实际上,接收者2 __did__在接收者1得到他的消息之前得到消息;他只是失去了首先将其写入文件的竞赛。如果将毫秒添加到日志配置中,则可能会更清晰一些,但可能不会。 – 2014-11-25 03:16:35
hmm ....“单个消费者的消息接收将按顺序进行,但不存在这样的保证,即消费者的下游处理将以任何顺序发生。”现在我明白了,谢谢:) – Dreamer 2014-11-25 19:02:40