JMS消息模型
在Jms标准中,有两种消息模型P2P(Point to Point),Publish/Subscriber。
P2P模式中包含sender,queue和receiver,即发送者,队列和接受者,该模式下,一个消息只能发送到一个队列,也只能被一个消费者消费。队列会保存消息直到消息被消费或者过期
P2P特点
- 每个消息只能被一个消费者消费,消费后就会消失(多对一的关系,一个消息一个消费者,一个消费者多个消息)
- 发送者和接受者之间没有依赖性,发送者只管将消息发送到队列,不关心是否有消费者等待消费
- 接受者接受消息,需要向发送者发送确认
Pub/Sub模式中包含publisher,subscriber和topic,即发布者,订阅者和主题
Pub/Sub特点
- 每个消息可以被多个消费者消费(多对多的关系)
- 发布者和订阅者之间存在依赖关系,只有订阅某个Topic,才能收到发布者的消息,即订阅者必须先创建才能收到消息
- 为了消费消息,订阅必须保证运行状态
但是持久化的订阅者,即使未能激活,也能在开启的时候接受到消费者的消息(即订阅,但不是不用在线)
Pub/Sub模式测试
代码地址:https://gitee.com/studycsw/pure-java
结果:
这里显示:在subscriber未启动的时候发送一条,启动之后在发送一条,很显然subscriber只监听到了后一条
在mq中的结果:
ActiveMq中从左到右的解读是:有1个消费者,发了两条消息,一条消息被消费
持久化的订阅者
消费者端的改变
先订阅主题
查看mq
有下线的持久化订阅者(offline Durable Topic Subscribers)
在开启生产者
再次开启订阅者
可以接受到消息
mq中也是正常显示
ActiveMq中的事务和签收
事务
在生产者中开启事务:
在未提交的时候是不会将消息存储到MQ中,只有生产者提交,消费者才能消费消息
在消费中开启事务:
结果
第一次启动能够拿到消息,未提交
第二次启动时,仍让能够拿到消息
在mq中就会显示消息未被消费
在消费中开启事务时如果不提交,会被消费者重复消费
签收
签收是相对于消费者的,在消费者端开启ClientAcknowledge时,只有对消息进行acknowledge,才能签收消息,否则会重复消费
从mq中可以看到,尽管消费者接收到消息,但是没有进行确认的情况下,仍然会有消息保存在mq中
签收和事务的关系
- 在事务会话中,当一个事务被成功提交则消息被自动签收
- 如果事务回滚,则消息会被再次发送
- 非事务回话中,消息何时被确认取决于创建会话时的确认模式(acknowledgement mode)
站在巨人的肩膀上
《阿里技术手册》