Java架构之jms基础

2 篇文章 0 订阅

JMS,即 Java Message Service(Java消息服务),是一个消息中间件。

假设A和B要沟通,要进行消息的传递,最基础的方式是直接沟通,A发送消息,B接收消息,但是这种方式下A和B之间的耦合太强,导致后期对代码和功能的扩展受限,极其不便,所以我们引入消息中间件的概念。消息中间件作为A和B之间消息沟通的桥梁。

JMS只定义了接口,并没有做出任何实现,实现JMS接口的消息中间件称为 JMS Provider, 市面上JMS Provider有很多,其中ActiveMQ是开源的一款性能优良的JMS Provider,并且是用java实现的。

JMS应用场景:
(1)可靠传输,数据不能丢失,有的时候会要求不能重复传输
(2)异步传输,提高传输效率
JMS的消息主要包括3部分:消息头,消息属性和消息体
应用的时候有两个部分的应用:
(1)JMS Producer:消息生产者,创建和发送消息
(2)JMS Consumer:消息消费者,接收和处理消息
消息的消费方式也分为两种:
(1)同步消费,通过调用消费者的receive方法,会阻塞,一直到消息到达消费者,接收到消息之后才会进行下一步的动作。
(2)异步消费,为消费者注册一个消息监听器,定义消息到达的时候所需要采取的下一步行动。消费者并不需要一直等待。

JMS有两种消息传递模式,点对点模式和发布/订阅模式。
(1)点对点模式:
这里写图片描述

1.一个消息只能有一个消费者,消费过了就没有这个消息了,最常见的是将消息存放在一个Queue(队列)中,供消费者使用,**这里有一个坑需要注意**,一个Queue可以有多个消费者,一个Queue中可以存多条消息,但是一条消息只能对应唯一的一个消费者。
2.消息的生产者和消费者之间没有时间上的相关性,它们都是分别对中间件负责就行,生产者负责将消息发到中间件(到此生产者的任务完成),消费者负责从中间件中取出消息,只要中间件中有消费者所需要的消息,不管什么时候,消费者都可以取用。(可以理解为异步)

(2)发布/订阅模式:
这里写图片描述

(1)每个消息可以有多个消费者,理解成一档广播节目,会有很多听众去订阅,当此节目更新之后,每个听众都会收到提醒。
(2)生产者和消费者有相关性,只有订阅了,才可以接收到消息,美誉订阅是无法及时收到更新通知。
(3)持久订阅和非持久订阅:持久订阅允许消费者消费它在未处于激活状态时发送的消息。即不在线的时候,仍可以订阅消息。

两种不同的模式,消息存储的地方不同,点对点存储在(Queue)队列中,发布/订阅存储在Topic(主题)中。

2018/5/3 更 。。。。。。。。。。。。。。。

以下是在具体的开发过程中,遇到的问题以及解决方案:
背景:
传统的jms架构只有两种消息传递模式,分别是Queue(点对点)和Topic(发布-订阅)。
区别在于,Queue(点对点)被消费之后就没有了,一个消息只能有一个消费者。
Topic(发布-订阅)可以有多个消费者,需要订阅此topic,只有订阅了才能收到后台推送的消息。

详细的解释请参考 ↑

需求 : 在传统的jms架构之上,根据业务需求,我们需要做到以下两点:
(1) 可以被重复消费,消费者只有订阅之后,才能收到推送消息。
(2) 需要固定的只推送给某一个或者某几个用户。
综上,我们最终采用的思路是利用topic,在topic原有的基础之上做改进,加入用户的Id,用作用户身份标识,以下采用topics作为名称,方便描述。

假设我们现在需要后台向app推送消息,普遍采用的做法是利用activeMQ作为消息中间件,java后台消息通过topics 和activeMQ进行通讯, app端和activeMQ采用mqtt方式进行通讯。
需要注意的是:
(1)后台需要主动推送消息给app端,app端只需要订阅该主题就行
(2)app有过滤消息的机制,避免收到垃圾消息浪费资源
(3) 每个app有自己的id,用来标识自己的身份。

2018/6/13更:
JMS消息结构之 “消息头” 组成:

1. JMSDeliveryMode: 传送模式,有两种模式,持久模式和非持久模式。
   区别在于持久模式不会丢失,如果服务器出现故障,在服务器恢复之后会再次传递。
   而非持久的消息最多会传递一次,如果服务器故障,该消息将永远消失。
   该模式可以在代码中直接配。
2. JMSExpiration: 消息的过期时间,可以设置成过期或者不过期。
   在send消息的过程中设置,如果被设置成永不过期,则消息会一直等待消费者来消费,永远不会过期。
   如果被设置一定的过期时间,则到一定时间会自动过期。
3. JMSPriority: 消息的优先级,有 0-9 共10个级别,0-4是普通消息,5-9是加急消息,加急消息必须先于普通消息到达,默认是4级
4. JMSMessageId: 唯一识别每个消息的标识,由JMS Provider产生
5. JMSTimestamp: 一个JMS Provider在调用send()方法时自动设置的。
6. JMS可以设置反馈,JMSReplyTo:提供本消息回复消息的目的地址,由开发者在代码中设置。
7. JMSRedelivered: 消费者收到某消息,但是未签收,所以该消息需要被重新传送,true表示被重新传送,false表示不被重新传送。

JMS消息结构之 “消息体” 组成:

JMS提供5种消息体格式:
1. TextMessage : 普通文本
2. MapMessage: map键值对格式
3. ObjectMessage: 对象格式
4. BytesMessage: 二进制格式
5. StreamMessage: 流媒体格式
即JMS可以传递以上5种类型的消息格式,发送消息方发送的格式类型必须和接收消息方接收的消息类型一致。

JMS的可靠性机制:
1 . JMS消息只有在被确认之后,才认为已经被成功消费,消息的成功消费包含三个阶段:客户接收消息,客户处理消息和消息被确认。
2 . 只有客户端确认提交(commit) 之后,才能确认消息已经被成功消费。
会话分为两种:事务性会话 和 非事务性会话

Session session = connection.createSession(Boolean.FALSE, session.AUTO_ACKNOWLEDGE);
第一个参数表示是否是事务性会话,true表示是,false表示否
第二个参数表示创建会话的应答模式
JMS session接口提供了commit和rollback方法,即本地事务,事务的提交意味着所有消息被发送,并且被确认,事务的回滚意味着所有消息被销毁,被消费的所有消息被恢复并且重新提交,除非已经过期。生产者和消费者不能包含在同一个事务中。
1. 在事务性会话中,当一个事务被提交的时候,确认自动发生
2. 在非事务性会话中,消息何时被确认取决于创建会话的应答模式
   session.AUTO_ACKNOWLEDGE: 当客户成功从receive方法返回的时候,会话自动确认
   session.CLIENT_ACKNOWLEDGE:客户端通过调用acknoeledge方法确认消息,该确认方式是会话层的,即确认一个消息,会伴随着确 
                               认该会话的所有消息

JMS消息的持久性:

JMS的 topic 需要注意的点:

两种消息提交模式:
PERSISTENT(persistent): JMS Provider持久保存消息,消息不会因为 JMS Provider的失败而丢失
NON_PERSISTENT: 不持久保存消息
1. 只有Queue是始终持久订阅的,消息不会丢失
2. 非持久订阅要求客户端和 JMS Provider必须处在连接状态,当客户端处于离线状态,这个时间段发到主题的消息将会丢失。
3. 持久订阅时,客户端向JMS注册一个识别自己身份的ID,客户端不管离线还是在线,都可以收到消息,消息不会丢失
4. 如果用户在 receive 方法中设定了消息选择条件,则不符合条件的消息不会被接收
5. 非持久订阅状态下,不能恢复或者重新派送一个未签收的消息,只有持久订阅才能做到
6. 当所有消息必须被接收,则用持久订阅,当丢失消息可以被容忍,则用非持久订阅

我们来看一下JMS的架构:
这里写图片描述
JMS的开发步骤(如上图所示):

1. 创建一个 JMS connection factory
2. 通过 connection factory 来创建连接(JMS Connection)
3. 启动 JMS Connection
4. 通过 connection 创建 session
5. 创建 destination
6. 创建 JMS Producer,或者创建 JMS message, 并设置 destination
7. 创建 JMS consumer,或者注册一个 JMS message Listener
8. 发送,接收 JMS message
9. 关闭所有的 JMS资源(connection, session, producer, consumer等)。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值