JMS 介绍

JMS(Java Message Service),即 Java 消息服务,是 JavaEE 中规范标准之一;用于在两个应用程序之间进行异步通信。本文主要介绍下 JMS 1.1 规范的基本内容并简要说明下 JMS 2.0。

1、基本概念

JMS Provider(提供者)  实现 JMS 接口规范的消息中间件,也就是 MQ 服务器

JMS Producer(生产者)  创建和发送 JMS 消息的客户端应用

JMS Consumer(消费者)  接收和处理 JMS 消息的客户端应用

JMS Message(消息)  消息由消息头、消息属性和消息体组成

JMS Queue(消息队列)  消息保存的地方,用于点对点的消息模型

JMS Topic(消息主题)  消息保存的地方,用于发布订阅的消息模型

2、JMS 消息模型

2.1、点对点消息模型(Point-to-Point Messaging Domain)

该消息模型的特点:

a、每个消息只有一个消费者,消息一旦被消费,就不在消息队列中了。
b、提供者和消费者之间在时间上没有依赖性,也就是说当提供者发送了消息之后,不管消费者有没有正在运行,它不会影响到消息被发送到队列。
c、每条消息仅会传送给一个消费者。可能会有多个消费者在一个队列中侦听,但是每个队列中的消息只能被队列中的一个消费者所消费。
d、消息存在先后顺序。一个队列会按照消息服务器将消息放入队列中的顺序,把它们传送给消费者。当已被消费时,就会从队列头部将它们删除(除非使用了消息优先级)。
e、消费者在成功接收消息之后需向队列应答成功。

2.2、发布/订阅消息模型(Publish/Subscribe Messaging Domain)

 该消息模型的特点:

a、每个消息可以有多个消费者
b、发布者和订阅者之间有时间上的依赖性。针对某个主题的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且只能消费订阅时间之后的消息;JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者宕机恢复后,也能接收宕机时生产者发布的消息。
d、每条消息都会传送给称为订阅者的多个消息消费者。
f、消息是被推送给消费者的。

3、JMS API 接口

ConnectionFactory  客户端用来创建连接的受管对象;可以通过 JNDI 来查找 ConnectionFactory 对象。

Connection  客户端到 JMS 提供者之间的活动连接。

Session  发送和接收消息的一个单线程上下文

Destination 由 Session 创建的 Queue 或 Topic 对象。

MessageProducer 由 Session创建的对象,用于发送消息到 Queue 或 Topic。

MessageCosumer 由 Session 创建的对象,用于接收 Queue 或 Topic 中的消息。

Message 消费者和生产者之间传送的数据。

MessageListener 消息监听器,消费者注册消息监听器,有消息到达,将调用该接口的 onMessage 方法。

4、JMS Message

JMS 消息由 消息头、消息属性、消息体 三部分组成。

4.1、消息头

JMSDestination  消息发送的目的地,主要有 Queue 和 Topic,它们都是 Destination 的实现。

JMSDeliveryMode:消息传输模式,有两种模式:持久化模式和非持久化模式;持久化的消息在消息服务器宕机后再重启不会丢失,而非持久化的消息则会丢失,可通过将消息设置为持久化来保证消息的可靠性,Queue 中的消息默认是持久化的,Topic 中的消息默认是非持久化的。

JMSExpiration:消息的过期时间,默认永不过期。若给 MessageProducer 对象设置了 timeToLive 属性值或者在调用 MessageProducer.send() 时指定了 timeToLive 的值,则消息将在 timeToLive 之后过期;如果设置 timeToLive 的值为 0,则永不过期,也可以给消息设置 JMSExpiration 属性值指定该消息的过期时间。消息发送后,在消息过期后若还没有被消费则会被清除。

JMSPriority  消息的优先级,有 0-9 十个级别,0-4 是普通消息,5-9 是加急消息。JMS 不要求 MQ 严格按照这十个优先等级发送消息,但必须保证加急消息先于普通消息到达目的地,默认的消息优先级是 4 级。

JMSMessageID  每条消息的唯一标识,默认由 MQ 产生,也可以自定义。

JMSTimestamp  消息发送时的时间。

JMSCorrelationID  关联的消息 ID,通常用在需要回传消息的时候。

JMSReplyTo  消息回复的目的地,其值为一个 Topic 或 Queue, 这个由发送者设置,但是接收者可以决定是否响应。

JMSRedelivered  消息是否重复发送过,如果该消息之前发送过,那么这个属性的值需要被设置为 true;客户端可以根据这个属性的值来确认这个消息是否重复发送过,以避免重复处理。

JMSType  消息类型,包括 TextMessage、BytesMessage、MapMessage、StreamMessage 和 ObjectMessage。

4.2、消息体

消息传输的内容

4.3、消息属性

消息属性可看作消息头的补充,消息属性按类型可以分为标准属性(JMSX 作为前缀),消息组件自定义的属性(JMS_ 作为前缀),以及应用自定义的属性。自定义的属性不要以前面两种为前缀。标准的JMSX属性如下:

5、消息的可靠性

消息的可靠性通过三个方面保证:消息的持久化、事务、消息的签收。

5.1、消息的持久化

消息的持久化是通过设置DeliveryMode实现的,DeliveryMode 有两种模式:
DeliveryMode.PERSISTENT:持久化,服务器宕机重启后消息依然存在
DeliveryMode.NON_PERSISTENT:非持久化,服务器宕机再重启消息将不存在

Queue 中的消息默认是持久化的,Topic中的消息默认是非持久化的。

对于 Topic,消费者采用 MessageConsumer 和采用 TopicSubscriber 消费消息是不同的,JMS 不会将 MessageConsumer 对象持久化(也就无法记录时间节点),但是会将 TopicSubscriber 对象持久化,这样就可以记录每个订阅者的订阅时间点,即使消费者掉线,也能在恢复后消费掉线时产生的消息;采用 TopicSubscriber 方式消费消息时需要消息持久化。

消息的持久化和消息的订阅模式是完全不同的两个概念,它们之间没有任何关系,只不过消息的持久化是否有意义需要参考消息的消费方式。

消息的持久化可以在两个地方设置:
a、调用生产者的 MessageProducer.setDeliveryMode() 方法,设置该生产者生产的所有消息的持久化模式,除非单独为某个消息设置了持久化模式
b、调用消息的 Message.setJMSDeliveryMode(),只设置这一条消息的持久化模式

5.2、事务

在通过 Connection 创建 Session 的时候可以指明这个 Session 下的消息生产者和消息消费者是否以事务的方式发送和消费消息:

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » JMS 介绍