JMS支持两种消息传递模型:点对点(point-to-point,简称PTP)和发布/订阅(publish/subscribe,简称pub/sub)。这两种消息传递模型非常相似,但有以下区别:
PTP消息传递模型规定了一条消息之恩能够传递费一个接收方。
Pub/sub消息传递模型允许一条消息传递给多个接收方
点对点模型
通过点对点的消息传递模型,一个应用程序可以向另外一个应用程序发送消息。在此传递模型中,目标类型是队列。消息首先被传送至队列目标,然后从该队列将消息传送至对此队列进行监听的某个消费者,如下图:
一个队列可以关联多个队列发送方和接收方,但一条消息仅传递给一个接收方。如果多个接收方正在监听队列上的消息,JMS Provider将根据“先来者优先”的原则确定由哪个价售房接受下一条消息。如果没有接收方在监听队列,消息将保留在队列中,直至接收方连接到队列为止。这种消息传递模型是传统意义上的拉模型或轮询模型。在此列模型中,消息不时自动推动给客户端的,而是要由客户端从队列中请求获得。
点对点模型的代码(springboot+jms+activemq)实现如下:
@Service("queueproducer")publicclassQueueProducer{@Autowired// 也可以注入JmsTemplate,JmsMessagingTemplate对JmsTemplate进行了封装privateJmsMessagingTemplate jmsMessagingTemplate;// 发送消息,destination是发送到的队列,message是待发送的消息@Scheduled(fixedDelay=3000)//每3s执行1次publicvoidsendMessage(Destination destination,finalString message){ jmsMessagingTemplate.convertAndSend(destination, message); }@JmsListener(destination="out.queue")publicvoidconsumerMessage(String text){ System.out.println("从out.queue队列收到的回复报文为:"+text); } }
Producer的实现
@ComponentpublicclassQueueConsumer2{// 使用JmsListener配置消费者监听的队列,其中text是接收到的消息@JmsListener(destination ="mytest.queue")//SendTo 该注解的意思是将return回的值,再发送的"out.queue"队列中@SendTo("out.queue")publicStringreceiveQueue(String text) { System.out.println("QueueConsumer2收到的报文为:"+text);return"return message "+text; } }
Consumer的实现
@RunWith(SpringRunner.class)@SpringBootTestpublicclassActivemqQueueTests{@AutowiredprivateQueueProducer producer;@TestpublicvoidcontextLoads()throwsInterruptedException { Destination destination =newActiveMQQueue("mytest.queue");for(inti=0; i<10; i++){ producer.sendMessage(destination,"myname is Flytiger"+ i); } } }
Test的实现
其中QueueConsumer2表明的是一个双向队列。
发布/订阅模型
通过发布/订阅消息传递模型,应用程序能够将一条消息发送到多个接收方。在此传送模型中,目标类型是主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的或送消费者。如下图:
主题目标也支持长期订阅。长期订阅表示消费者已注册了主题目标,但在消息到达目标时该消费者可以处于非活动状态。当消费者再次处于活动状态时,将会接收该消息。如果消费者均没有注册某个主题目标,该主题只保留注册了长期订阅的非活动消费者的消息。与PTP消息传递模型不同,pub/sub消息传递模型允许多个主题订阅者接收同一条消息。JMS一直保留消息,直至所有主题订阅者都接收到消息为止。pub/sub消息传递模型基本上是一个推模型。在该模型中,消息会自动广播,消费者无须通过主动请求或轮询主题的方法来获得新的消息。