JMS基本概念
简介
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
JMS是一种与厂商无关的 API,用来访问消息收发系统消息,它类似于JDBC(Java Database Connectivity)。这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。许多厂商都支持 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ。 JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JMS客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为几种类型,它们分别携带:简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。
专业技术规范
JMS(Java Messaging Service)是Java平台上有关面向消息中间件(MOM)的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发,翻译为Java消息服务。
体系架构
JMS提供者: 连接面向消息中间件的,JMS接口的一个实现。提供者可以是Java平台的JMS实现,也可以是非Java平台的面向消息中间件的适配器。
JMS客户: 生产或消费基于消息的Java的应用程序或对象。
JMS生产者: 创建并发送消息的JMS客户。
JMS消费者: 接收消息的JMS客户。
JMS消息: 包括可以在JMS客户之间传递的数据的对象。
JMS队列: 一个容纳那些被发送的等待阅读的消息的区域。与队列名字所暗示的意思不同,消息的接受顺序并不一定要与消息的发送顺序相同。一旦一个消息被阅读,该消息将被从队列中移走。
JMS主题: 一种支持发送消息给多个订阅者的机制。
对象模型
连接工厂: 连接工厂(ConnectionFactory)是由管理员创建,并绑定到JNDI树中。针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。客户端使用JNDI查找连接工厂,然后利用连接工厂创建一个JMS连接。
JMS连接: JMS连接(Connection)表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。
JMS会话: JMS会话(Session)表示JMS客户与JMS服务器之间的会话状态。JMS会话建立在JMS连接上,表示客户与服务器之间的一个会话线程。Session是我们操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。
JMS目的: JMS目的(Destination),又称为消息队列,是实际的消息源。Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。
JMS生产者: 生产者(Message Producer)对象由Session对象创建,用于发送消息。用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息。
JMS消费者: 消费者(Message Consumer)对象由Session对象创建,用于接收消息。接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。
消息监听器: 如果注册了消息监听器(MessageListener),一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一种MessageListener。
消息模型
(一). 点对点模型
点对点(Point-to-Point)。在点对点的消息系统中,消息分发给一个单独的使用者。点对点消息往往与队列(javax.jms.Queue)相关联。
1. P2P模式图
2. 涉及到的概念
- 消息队列(Queue)
- 发送者(Sender)
- 接收者(Receiver)
3. P2P的特点
- 每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。
- 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
- 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
- 接收者在成功接收消息之后需向队列应答成功
如果你希望发送的每个消息都应该被成功处理的话,那么你需要P2P模式。
4. 消息的消费
在这种模式下消息的产生和消费是异步的。就是说生产和消费可以不同时发生,生产的消息在队列中,等消费者上线之后可以消费。对于消费来说,JMS的消费者可以通过两种方式来消费消息。
- 同步: 接收者调用receive方法来接收消息,receive方法在能够接收到消息之前(或超时之前)将一直阻塞
- 异步: 接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。
(二). 发布/订阅模型
发布/订阅消息系统支持一个事件驱动模型,消息生产者和消费者都参与消息的传递。生产者发布事件,而使用者订阅感兴趣的事件,并使用事件。该类型消息一般与特定的主题(javax.jms.Topic)关联。
1. Pub/Sub模式图
2. 涉及到的概念
- 主题(Topic)
- 发布者(Publisher)
- 订阅者(Subscriber)
3. Pub/Sub的特点
- 每个消息可以有多个消费者。客户端将消息发送到主题。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
- 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。
- 为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
如果你希望发送的消息可以不被做任何处理、或者被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型
4. 消息的消费
在这种模式下,也可以说消息的发布与订阅是异步的,但是要求先订阅,然后订阅者才能收到发布者发布的消息。对于订阅者来说,JMS的订阅者可以通过两种方式来消费消息。
- 同步: 订阅者调用receive方法来接收消息,receive方法在能够接收到消息之前(或超时之前)将一直阻塞
- 异步: 订阅者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。
传递方式
JMS有两种传递消息的方式。
- 标记为NON_PERSISTENT的消息最多投递一次
- 标记为PERSISTENT的消息将使用暂存后再转送的机理投递。
如果一个JMS服务离线,那么持久性消息不会丢失但是得等到这个服务恢复联机时才会被传递。所以默认的消息传递方式是非持久性的。即使使用非持久性消息可能降低内务和需要的存储器,并且这种传递方式只有当你不需要接收所有的消息时才使用。
虽然JMS规范并不需要JMS供应商实现消息的优先级路线,但是它需要递送加快的消息优先于普通级别的消息。JMS定义了从0到9的优先级路线级别,0是最低的优先级而9则是最高的。更特殊的是0到4是正常优先级的变化幅度,而5到9是加快的优先级的变化幅度。
举例来说:
//Pub-Sub
topicPublisher.publish (message, DeliveryMode.PERSISTENT, 8, 10000);
//或
//P2P
queueSender.send(message,DeliveryMode.PERSISTENT, 8, 10000);
这个代码片断,有两种消息模型,映射递送方式是持久的,优先级为加快型,生存周期是10000 (以毫秒度量)。如果生存周期设置为零,这则消息将永远不会过期。当消息需要时间限制否则将使其无效时,设置生存周期是有用的。
JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。
- StreamMessage -- Java原始值的数据流
- MapMessage -- 一套名称-值对
- TextMessage -- 一个字符串对象
- ObjectMessage -- 一个序列化的 Java对象
- BytesMessage -- 一个未解释字节的数据流
参考:
JMS
ggyoujian: https://blog.csdn.net/kongfanyu/article/details/109639616 请观摩(反例)
ggyoujian: 您这篇标注了转载,且根据您的整理后,逻辑是对的,有个人和您排版一样,没有标注转载,它保留了一些原文,导致逻辑不对,有点可笑了
mantle2014: conda就是我的神!!!没有你我怎么活啊!!!谢谢作者分享,终于安上了
mantle2014: 有的呀,安装的不就是解释器嘛,输入R就可以打开了
SuasyYi: 写得很棒!