了解 JMS
了解 JMS
1、前言
越来发现自己太渣,难道这就是传说中的“知道的越多,不知道的越多”?不!我相信我是确实不知道的有很多……[捂脸]
言归正传,最近使用到了 ActiveMQ,发现这个玩意儿也是非常重要且有用!继 Mongo 专栏之后,计划以同样的 style 来从零开始学习一下 ActiveMQ。
顺便吐槽一下:别说,这 Markdown 还确实挺好用嘿!不过不支持排版缩进什么鬼啊???还得用   或  ,这让强迫症表示根本无法自拔好嘛……
2、JMS 简介
学习 ActiveMQ 之前,先来学习一下 JMS:
JMS(Java Messaging Service),即Java消息服务,是Java平台上关于面向消息中间件(MOM)的API,它便于应用程序之间,或分布式系统之间进行异步的消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。
JMS 是 Java 消息服务的标准(或者叫规范),它使分布式通信耦合更低,消息服务更加可靠,这个标准在企业应用中十分的重要和广泛,所以开篇来重点学习一下它。好了,必要的概念大致就这么多,其他细节网上还有很多,不再赘述。
3、消息的模型
点对点队列模型:Point-to-Point(P2P)
发布订阅模型:Publish/Subscribe(Pub/Sub)
3.1、P2P 模型

3.1.1、相关对象
- 消息队列(Queue)
- 发送者(Sender)
- 接收者(Receiver)
3.1.2、过程
发送者将消息发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被接收者消费或超时。
3.1.3、特点
- 每个消息只有一个消费者(Consumer),消息一旦被消费就会从队列中移除
- 发送者和接收者在时间上没有依赖性(异步),即发送者发送消息时接收者无需处于运行状态,同样接收者接收消息时发送者无需处于运行状态
- 接收者接收消息之后需向队列应答成功
3.2、Pub/Sub 模型

3.2.1、相关对象
- 主题(Topic)
- 发布者(Publisher)
- 订阅者(Subscriber)
3.2.2、过程
发布者向一个特定的主题发布消息,0或多个订阅者可能对该特定主题的消息感兴趣并接收;这种模型下,发布者和订阅者彼此不知道对方。
3.2.3、特点
- 每个消息可以有多个消费者
- 发布者和订阅者之间有时间上的依赖性。订阅者必须保持持续的运行状态才能接收到消息
JMS提供了持久化订阅,这时候,订阅者未连接主题时(发布者)发布的消息,将在订阅者重新连接时进行重新发布,以便订阅者接收消息
4、消息的消费
在 JMS 中,消息的产生和消息是异步的。对于消费来说,JMS 的消息者可以通过两种方式来消费消息。
- 同步:接收者或订阅者调用
receive()方法来接收消息,消息到达(或超时)之前将一直阻塞。 - 异步:接收者或订阅者可以注册为一个消息监听器,当消息到达之后,系统会自动调用监听器的
onMessage方法。
5、消息的组成
消息传递系统的中心就是消息,一条消息由三个部分组成:头、属性、主体。
5.1、头(head)
每条 JMS 消息都必须具有消息头。头字段包含用于路由和识别消息的值。可以通过多种方式来设置消息头的值:
- 由
JMS提供者在生成或传送消息的过程中自动设置 - 由生产者客户机通过在创建消息生产者时指定的设置进行设置
- 由生产者客户机逐一对各条消息进行设置
5.2、属性(property)
消息可以包含称作属性的可选头字段。他们是以属性名和属性值对的形式制定的。可以将属性是为消息头得扩展,其中可以包括如下信息:创建数据的进程、数据的创建时间以及每条数据的结构。JMS 提供者也可以添加影响消息处理的属性,如是否应压缩消息或如何在消息生命周期结束时废弃消息。
5.3、主体(body)
包含要发送的内容。每个消息接口特定于它所支持的内容类型。JMS 为不同类型的内容提供了他们各自的消息类型,但是所有消息都派生自 Message 接口。
StreamMessage:一种主体中包含Java基元值流的消息。其填充和读取均按顺序进行。MapMessage:一种主体中包含一组键值对的消息。没有定义条目顺序。TextMessage:一种主体中包含Java字符串的消息(例如,XML消息)。ObjectMessage:一种主体中包含序列化Java对象的消息。BytesMessage:一种主体中包含连续字节流的消息。
6、JMS 编程模型
6.1、ConnectionFactory(连接工厂)
创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。
6.2、Destination(目标)
Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。
所以,Destination实际上就是两种类型的对象:Queue、Topic可以通过JNDI来查找Destination。
6.3、Connection(连接)
Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。
6.4、Session(会话)
Session是我们操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。
6.5、MessageProducer(消息生产者)
消息生产者由Session创建,并用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息。
6.6、MessageConsumer(消息消费者)
消息消费者由Session创建,用于接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。
6.7、Message(消息)
是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。
6.8、MessageListener
消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的 onMessage 方法。

