JMS

一、概念

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

2. Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持

3. Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持JAVA应用程序开发

4. 在J2EE中,当两个应用程序使用JMS进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务连接起来,可以达到解耦的效果

5. JMS同样适用于基于事件的应用程序,如聊天服务,它需要一种发布事件机制向所有与服务器连接的客户端发送消息。JMS与RMI不同,发送消息的时候,接收者不需要在线。服务器发送了消息,然后就不管了;等到客户端上线的时候,能保证接收到服务器发送的消息。这是一个很强大的解决方案,能处理当今世界很多普遍问题

6. 优势:

	1)异步:JMS天生就是异步的,客户端获取消息的时候,不需要主动发送请求,消息会自动发送给可用的客户端。

	2)可靠:JMS保证消息只会递送一次。大家都遇到过重复创建消息问题,而JMS能帮你避免该问题

二、JMS消息传送模型

在JMS API出现之前,大部分产品使用“点对点”和“发布/订阅”中的任一方式来进行消息通讯。JMS定义了这两种消息发送模型的规范,它们相互独立。任何JMS的提供者可以实现其中的一种或两种模型,这是它们自己的选择。JMS规范提供了通用接口保证我们基于JMS API编写的程序适用于任何一种模型。

1. 点对点

在这里插入图片描述

1)概念
(1)在点对点消息传送模型中,应用程序由消息队列,发送者,接收者组成

(2)每一个消息发送给一个特殊的消息队列,该队列保存了所有发送给它的消息(除了被接收者消费掉的和过期的消息)
2)特性
(1)每个消息只有一个接收者

(2)消息发送者和接收者并没有时间依赖性

(3)当消息发送者发送消息的时候,无论接收者程序在不在运行,都能获取到消息

(4)当接收者收到消息的时候,会发送确认收到通知(acknowledgement)
2. 发布/订阅

在这里插入图片描述

1)概念
(1)在发布/订阅消息模型中,发布者发布一个消息,该消息通过topic传递给所有的客户端

(2)在这种模型中,发布者和订阅者彼此不知道对方,是匿名的且可以动态发布和订阅topic

(3)topic主要用于保存和传递消息,且会一直保存消息直到消息被传递给客户端
2)特性
(1)一个消息可以传递给多个订阅者

(2)发布者和订阅者有时间依赖性,只有当客户端创建订阅后才能接受消息,且订阅者需一直保持活动状态以接收消息	

(3)为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息
3. 接收消息方式
1)同步:使用同步方式接收消息的话,消息订阅者调用receive()方法。在receive()中,消息未到达或在到达指定时间之前,方法会阻塞,直到消息可用

2)异步:使用异步方式接收消息的话,消息订阅者需注册一个消息监听者,类似于事件监听器,只要消息到达,JMS服务提供者会通过调用监听器的onMessage()递送消息	

三、JMS编程接口

JMS应用程序由如下基本模块组成:

在这里插入图片描述

1. 管理对象(Administered objects):连接工厂(Connection Factories)和目的地(Destination)

管理对象(Administered objects)是预先配置的JMS对象,由系统管理员为使用JMS的客户端创建,主要有两个被管理的对象:

1)连接工厂(ConnectionFactory)

	(1)客户端使用一个连接工厂对象连接到JMS服务提供者,它创建了JMS服务提供者和客户端之间的连接

	(2)JMS客户端(如发送者或接受者)会在JNDI名字空间中搜索并获取该连接。使用该连接,客户端能够与目的地通讯,往队列或话题发送/接收消息

	(3)创建Connection对象的工厂,针对两种不同的JMS消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。

2)目的地(Destination)

	(1)目的地指明消息被发送的目的地以及客户端接收消息的来源。JMS使用两种目的地,队列和话题	

	(2)Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)
2. JMS连接(Connection)
(1)连接对象封装了与JMS提供者之间的虚拟连接,如果我们有一个ConnectionFactory对象,可以使用它来创建一个连接	

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

(3)创建完连接后,需要在程序使用结束后关闭它
3. JMS 会话(Session)
(1)Session是一个单线程上下文,用于生产和消费消息,可以创建出消息生产者和消息消费者

(2)Session对象实现了Session接口,在创建完连接后,我们可以使用它创建Session

(3)Session是操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。
4. JMS消息生产者(MessageProducer)
(1)消息生产者由Session创建,用于往目的地发送消息。生产者实现MessageProducer接口,我们可以为目的地、队列或话题创建生产者

(2)创建完消息生产者后,可以使用send方法发送消息

(3)消息生产者由Session创建,并用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息
5. JMS消息消费者(MessageConsumer)
(1)消息消费者由Session创建,用于接受目的地发送的消息。消费者实现MessageConsumer接口,我们可以为目的地、队列或话题创建消费者

(2)消息消费者由Session创建,用于接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者
6. JMS消息监听器(MessageListener)
(1)JMS消息监听器是消息的默认事件处理者,他实现了MessageListener接口,该接口包含一个onMessage方法,在该方法中需要定义消息达到后的具体动作

(2)通过调用setMessageListener方法我们给指定消费者定义了消息监听器

四、JMS消息结构

1. 消息头(JMS消息头预定义了若干字段用于客户端与JMS提供者之间识别和发送消息)

自动分配的消息头(在传送消息时,消息头的值由JMS提供者来设置,因此开发者使用setJMSxxx()方法分配的值就被忽略了):

1)JMSDestination		消息发送的目的地,是一个Topic或Queue

2)JMSDeliveryMode      消息的发送模式,分为NON_PERSISTENT和PERSISTENT,即非持久性模式的和持久性模式。默认设置为PERSISTENT(持久性)

	(1)一条持久性消息应该被传送一次(就一次),这就意味着如果JMS提供者出现故障,该消息并不会丢失; 它会在服务器恢复正常之后再次传送

	(2)一条非持久性消息最多只会传送一次,这意味着如果JMS提供者出现故障,该消息可能会永久丢失

	(3)在持久性和非持久性这两种传送模式中,消息服务器都不会将一条消息向同一消息者发送一次以上(成功算一次)

3)JMSMessageID	        消息ID,需要以ID:开头,用于唯一地标识一条消息

4)JMSTimestamp         消息发送时的时间。这条消息头用于确定发送消息和它被消费者实际接收的时间间隔。时间戳是一个以毫秒来计算的Long类型时间值(自1970年1月1日算起)

5)JMSExpiration        消息的过期时间,以毫秒为单位,用来防止把过期的消息传送给消费者。任何直接通过编程方式来调用setJMSExpiration()方法都会被忽略

	(1)可以用topicPublisher.setTimeToLive(3600000);

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

7)JMSPriority           消息的优先级,0-4为普通的优化级,而5-9为高优先级,通常情况下,高优化级的消息需要优先发送。任何直接通过编程方式调用setJMSPriority()方法都将被忽略

	(1)可以用topicPublisher.setPriority(9);

开发者分配的消息头:

1)JMSCorrelationID		关联的消息ID,这个通常用在需要回传消息的时候

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

3)JMSType              由消息发送者设置的消息类型,代表消息的结构,有的消息中间件可能会用到这个,但这个并不是是批消息的种类,比如TextMessage之类的

注:

(1)从上表中我们可以看到,系统提供的标准头信息一共有10个属性,其中有6个是由send方法在调用时设置的,有三个是由客户端(client)设置的,还有一个是由消息中间件(Provider, JMSRedelivered属性)设置的

(2)这里的客户端(client)不是指消费者,而是指使用JMS的客户端,即开发者所写的应用程序,即在生产消息时,这三个属性是可以由应用程序来设定的,而其它的header要么由消息中间件设置,要么由发送方法来决定,开发者即使设置了,也是无效的
2. 消息属性
1)我们可以给消息设置自定义属性,这些属性主要是提供给应用程序的。对于实现消息过滤功能,消息属性非常有用,JMS API定义了一些标准属性,JMS服务提供者可以选择性的提供部分标准属性。

2)消息的属性就像可以分配给一条消息的附加消息头一样。它们允许开发者添加有关消息的不透明附加信息。它们还用于暴露消息选择器在消息过滤时使用的数据	

3)Message接口为读取和写入属性提供了若干个取值函数和赋值函数方法。消息的属性值可以是String, boolean , byte,short, double, int ,long或float型。Message接口为每种类型的属性值都提供了取值函数和赋值方法
3. 消息体

在消息体中,JMS API定义了五种类型的消息格式,让我们可以以不同的形式发送和接受消息,并提供了对已有消息格式的兼容

1)TextMessage					最简单的消息接口,用于发送文本类的消息,设置/获取其body的方法定义如下setText()/getText()

2)ObjectMessage                将对象作为消息的接口,提供了一个set/get 对象的方法,需要注意的是只能设置一个对象,这个对象可以是一个Collection,但必须是序列化的

3)MapMessage                   把消息内容存储在Map里,本接口定义了一系列对基本类型的的set/get方法,与StreamMessage不同的是,每个值都对应了一个相应的key,所以消息接收者不必按顺序去读取数据

4)StreamMessage             	流式消息接口,里面定义了一系列的对基本类型的set/get方法,消息发送者可以通过这些方法写入基本类型的数据,消息接收者需要按发送者的写入顺序来读取相应的数据

5)BytesMessage                 以字节的形式来传递消息的接口,除了提供了对基本类型的set/get,还提供了按字节方式进行set/get

参考网址

JMS(Java消息服务)入门教程

1,Java消息服务-JMS

基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值