JMS

450 阅读5分钟

什么是JMS?

JMS(Java Message Service)即Java消息服务应用程序接口,是Java平台中面向消息中间件的一套规范的JavaAPI接口,用于在两个应用程序之间或分布式系统中发送消息,进行异步通信。

JMS的作用:

提供通用接口保证基于JMS API编写的程序适用于任何一种模型, 使得在更换消息队列提供商的情况下应用程序相关 代码也不需要做太大的改动。

类比:

使用JMS API来连接支持AMQP、STOMP等协议的消息中间件产品(比如 ActiveMQ、 RabbitMQ 等),在这一点上它与Java中的JDBC的作用很像,我们可以用 JDBC API 来访问具体的数据库产品( 比如 Oracle、 MySQL 等)。

历史版本:

JMS这套规范由SUN提出,目前主要使用的版本有两个:
一个是2002年发布的 1.1 版。
一 个是2013年发布的2.0版。
JMS并不是消息队列协议的一种,更不是消息队列产品,它是与具体平台无关的 API, 目前市面上的绝大多数消息中间件厂商都支持JMS接口规范。

JMS的消息模型

两种消息队列模式:点对点和发布/订阅两种方式

(1)点对点模型

  • 在点对点(Point to Point)模型中,应用程序由队列(Queue)、发送者( Sender)和接收者 (Receiver)组成。

  • 每条消息都被发送到一个特定的队列中,接收者从队列中获取消息。队列中一直保留着消息,直到它们被接收或超时。

点对点模型的特点如下:

  • 每条消息只有一个接收者,消息一旦被接收就不再保留在消息队列中了。发送者和接收者之间在时间上没有依赖。也就是说,当消息被发送之后,不管接收者有没有在运行,都不会影响消息被发送到队列中。

  • 每条消息仅会被传送给一个接收者。也就是说,一个队列中可能会有多个接收者在监听,但是消息只能被队列中的一个接收者接收。

  • 消息存在先后顺序。一个队列会按照消息服务器将消息放入队列中的顺序把它们传送给接收者。当消息己经被接收时就会从队列头部将它们删除(除非使用了消息优先级)。

  • 当接收者收到消息时,会发送确认收到通知。

一般情况下,如果希望所发送的每条消息都能被成功处理,则需要使用点对点模型。

点对点模型
(2)发布/订阅模型

  • 在发布/订阅(Pub/Sub)模型中,应用程序由主题(Topic)、发布者(Publisher) 和订阅者 (Subscriber)组成。

  • 发布者发布一条消息,该消息通过主题传递给所有的订阅者。

  • 在这种模型中,发布者和订阅者彼此不知道对方,它们是匿名的井且可以动态发布和订阅主题。

  • 主题用于保存和传递消息,并且会一直保存消息直到消息被传递给订阅者。

发布/订阅模型的特点如下:

  • 每条消息可以有多个订阅者。

  • 发布者和订阅者之间有时间上的依赖。

  • 一般情况下,某个主题的订阅者需要在创建了订阅之后才能接收到消息,而且为了接收消息订阅者必须保持运行的状态。

  • JMS允许订阅者创建一个可持久化的订阅,这样即使订阅者没有运行也能接收到所订阅的消息。

  • 每条消息都会传送给该主题下的所有订阅者。

  • 通常发布者不会知道也意识不到哪一个订阅者正在接收消息。

所以,如果希望所发送的消息不被做任何处理或者被一个或多个订阅者处理,则可以使用 发布/订阅模型。

JMS编程模型 

(1) ConnectionFactory 接口(连接工厂)
ConnectionFactory 是创建 Connection 对象的工厂,根据不同的消息类型用户可选择用队列 连接工厂或者主题连接工厂,分别对应 QueueConnectionF actory 和 TopicConnectionFactory。 可以通过 JNDI 来查找 ConnectionFactory 对象。

(2) Destination 接口(目的地)
Destination 是一个包装了消息目的地标识符的受管对象。 消息目的地是指消息发布和接收 的地点,消息目的地要么是队列要么是主题。对于消息生产者来说,它的 Destination 是某个队 列或某个主题:对于消息消费者来说,它的 Destination 也是某个队列或主题( 即消息来源)。 所以 Destination 实际上就是两种类型的对象: Queue和 Topic, 可以通过 JNDI 来查找 Destination。

(3) Connection 接口(连接)
Connection 表示在客户端和 JMS 系统之间建立的连接(实际上是对 TCP/IP Socket 的包装)。 Connection 可以产生一个或多个 Session,跟 ConnectionFactory一样, Connection 也有两种类型: QueueConnection 和 TopicConnection。

(4) Session 接口(会话)
Session 是实际操作消息的接口,表示一个单线程的上下文,用于发送和接收消息。因为会 话是单线程的,所以消息是按照发送的顺序一个个接收的。可以通过 Session 创建生产者、消费 者、消息等。在规范中 Session 还提供了事务的功能。 Session 也分为两种类型: QueueSession 军日 TopicSession。

( 5) MessageProducer 接口(消息生产者〉
消息生产者由 Session 创建并用于将消息发送到 Destination。 消费者可以同步(阻塞模式) 或异步(非阻塞模式)接收队列和主题类型的消息。消息生产者有两种类型: QueueSender 和 TopicPublisher。

( 6) MessageConsumer 接口(消息消费者)
消息消费者由 Session 创建,用于接收被发送到 Destination 的消息。消息、消费者有两种类 型: QueueReceiver 和 TopicSubscriber。

( 7 ) Message 接口(消息〉
消息是在消费者和生产者之间传送的对象,即将消息从一个应用程序发送到另一个应用程序。

( 8 ) MessageListener (消息监昕器)
如果注册了消息监听器, 那么当消息到达时将自动调用监昕器的 onMessage 方法。