JMS解析——JMS简介
Posted 踩踩踩从踩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JMS解析——JMS简介相关的知识,希望对你有一定的参考价值。
消息中间件MQ及ActiveMQ介绍_踩踩踩从踩的博客-CSDN博客
前言
上篇文章对消息中间件做了个解析,以及ActiveMQ的安装和基本使用,做了个基本了解,因为如果不了JMS规范,一定是不学不好消息中间件和ActiveMQ,本篇文章会从JMS是什么,以及JMS如何使用API,消息如何发送,消息模型等等去解析JMS
概述
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
也就是java消息操作标准API。
为程序员制定的,少写代码,又可以操作消息中间件而提供的标准API规范, 对于应用来说只需要关心接口就行,而不管是那个消息中间件厂商实现。
对比的是jdbc连接数据库,我们只关心接口的api是什么,而不用关心具体是那个数据库去实现的;这也是简化程序员开发的场景。但有时候,为提高效率执行我们又不得不去关心,他是如何实现和执行的。那都是后话了
API
发展历史
出于历史原因,JMS为发送和接收提供了四组可选接口信息。
- JMS 1.0定义了两个特定于域的API,一个用于点对点消息传递(队列)和一个用于发布/订阅(主题)。尽管由于向后的原因,这些仍然是JMS的一部分兼容性它们应该被认为是完全被后来的API所取代。
- JMS 1.1引入了一个新的统一API,它提供了一组可以用于点对点和发布/订阅消息。这里称之为经典API
- JMS 2.0引入了一个简化的API,它提供了经典API的所有特性,但需要更少的接口,使用更简单
- 每个API都提供了一组不同的接口,用于连接JMS提供程序和发送数据和接收消息。但是,它们都共享一组用于表示消息和消息目的地,并提供各种实用程序功能。
所有接口都在javax.jms包中。
ActiveMQ 5 实现的就是 JMS1.1 规范
经典api构成
经典API提供的主要接口如下:
- ConnectionFactory—客户端用于创建连接的受管对象。这接口也被简化的API使用。
- Connection-到JMS提供程序的活动连接
- Session-用于发送和接收消息的单线程上下文
- MessageProducer—由会话创建的对象,用于向服务器发送消息队列或主题
- MessageConsumer—由用于接收消息的会话创建的对象发送到队列或主题
简化api构成
简化API提供与经典API相同的消息传递功能,但需要接口更少,使用更简单。简化API提供的主要接口如下:
- ConnectionFactory—客户端用于创建连接的受管对象。这接口也被经典API使用。
- JMSContext—到JMS提供程序的活动连接和的单线程上下文发送和接收消息
- JMSProducer—由JMSContext创建的对象,用于将消息发送到队列或主题
- JMSConsumer—由JMSContext创建的对象,用于接收发送的消息到队列或主题
在简化的API中,单个JMSContext对象包含经典API中的行为API由两个独立的对象提供,一个连接和一个会话。虽然本规范将JMSContext称为具有底层“连接”和“会话”,即简化的API不使用连接和会话接口。
在activemq代码中 都是jms 包下面的操作,包括连接 session等等。
在jar包中源码就能看出来,我们使用的时候全是接口
API在使用时,注意对多线程情况下的处理 包括目标 连接这些都是并发安全的。但会话等 都不是线程安全的。
在api使用过程 ,一定要start ,但并不是连接创建成功就必须要start,也可以 发送消息时,进行start都可以
包括提供了停止服务,也可以在重复启动,停止;也包括了 close 关闭方法
jms支持的消息传递方式
JMS支持企业消息传递产品提供的两种主要消息传递样式:
- 点对点(PTP)消息传递允许客户端通过中间抽象称为队列。发送消息的客户端将消息发送到特定队列。接收消息的客户端从该队列中提取消息。
-
发布和订阅(pub/sub)消息允许客户端向多个服务器发送消息客户端通过称为主题的中间抽象。发送消息的客户端将其发布到特定主题。然后将消息传递给所有正在访问的客户端同意这个主题。
JMS消息模型
- Header—所有消息都支持相同的标题字段集。标题字段包含值由客户端和提供者用于识别和路由消息。这里时不允许添加数据的
- 属性-除了标准的头字段外,消息还为向消息中添加可选的标题字段。特定于应用程序的属性—实际上,这提供了一种添加应用程序特定的消息头字段。标准属性-JMS定义了一些实际上是可选的标准属性标题字段。特定于提供者的属性–某些JMS提供者可能需要使用特定于提供者的属性。JMS为这些文件定义了命名约定。 和头差不多
- Body-JMS定义了几种类型的消息体,涵盖了大部分消息传递当前正在使用的样式。
消息头的信息
包括那个实现,大部分都是 提供者也就是厂商实现的
头字段名
|
说明
|
Set By
|
Setter method
|
JMSDestination
|
消息的目的地,
Topic
或者是
Queue
|
JMS
provider
send
method
|
setJMSDestination (not for
client use)
|
JMSDeliveryMode
|
消息的发送模式
|
JMS
provider
send
method
|
setJMSDeliveryMode(not
for client use)
|
JMSTimestamp
|
际发送的时间
|
JMS
provider
send
method
|
setJMSDeliveryMode(not
for client use)
|
JMSExpiration
|
消息的有效期,在有效期内,消息消费者
才可以消费这个消息
|
JMS
provider
send
method
|
setJMSDeliveryMode(not
for client use)
|
JMSPriority
|
消息的优先级。
0-4
为正常的优先级,
5-9
为高优先级
|
JMS
provider
send
method
|
setJMSDeliveryMode(not
for client use)
|
JMSMessageID
|
一个字符串用来唯一标示一个消息
|
JMS
provider
send
method
|
setJMSDeliveryMode(not
for client use)
|
JMSReplyTo
|
有时消息生产者希望消费者回复一个消
息,
JMSReplyTo
为一个
Destination
,表
示需要回复的目的地
|
Client
application
|
setJMSReplyTo
|
JMSCorrelationID
|
通常用来关联多个
Message
|
Client
application
|
setJMSCorrelationID,
setJMSCorrelationIDAsByte
|
JMSType
|
表示消息体的结构,和
JMS
提供者有关
|
Client
application
|
setJMSType
|
JMSRedelivered
|
如果这个值为
true
,表示消息是被重新发
送了
|
JMS
provider
prior to
delivery
|
setJMSRedelivered (not for
client use)
|
在发送消息之前,应用程序可以使用消息对象上的方法来设置JMSCorrelationID、JMSReplyTo和JMSType消息头。
在代码设置模式
Message properties
当我们需要执行自己添加的一些对消息内容添加标识等自定义的属性时,用到该字段
- 属性名字
属性名称必须遵守消息选择器标识符的规则。见第3.8节“信息“选择”以获取更多信息。
- 属性值
属性值可以是布尔值、字节值、短值、int值、长值、浮点值、双精度值和字符串。
设置属性:
在发送消息之前,客户端应用程序可以使用消息对象上的方法来设置消息属性
消息体
消息发送
消息发送 中涉及到 同步发送、异步发送、发送有过期时间消息、发送延时消息、发送更优先的消息、设置消息的传递格式、消息顺序等
同步发送
在经典API中,MessageProducer上的以下方法可用于发送消息
同步地:
- 发送(消息)
- 发送(消息消息、整数传递模式、整数优先级、长时间生存)
- 发送(目的地、消息消息、int-deliveryMode、int-priority、long)
- 时间(寿命)
- 发送(目的地、消息)
这些方法将一直阻止,直到消息被发送。如有必要,呼叫将被阻止,直到
已从JMS服务器接收回确认消息。
异步发送
在经典API中,MessageProducer上的以下方法可用于发送消息异步
- 发送(消息消息,CompletionListener CompletionListener)
- 发送(消息消息、int-deliveryMode、int-priority、long-timeToLive、CompletionListener)completionListener)
- 发送(目标、消息消息、CompletionListener CompletionListener)
- 发送(目的地、消息消息、int-deliveryMode、int-priority、long)timeToLive,CompletionListener(CompletionListener)
使用例子 主要是通过转换一次才能得到数据。
// 5、用目的地创建消息生产者
MessageProducer producer = session.createProducer(destination);
// 设置递送模式(持久化 / 不持久化)
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
// 6、创建一条文本消息
String text = "Hello world! From: " + Thread.currentThread().getName() + " : "
+ System.currentTimeMillis();
TextMessage message = session.createTextMessage(text);
// 7、通过producer 发送消息
System.out.println("Sent message: " + text);
// 异步方式发送某条消息
((ActiveMQMessageProducer) producer).send(message, new AsyncCallback() {
@Override
public void onException(JMSException exception) {
// TODO Auto-generated method stub
}
@Override
public void onSuccess() {
try {
System.out.println(Thread.currentThread().getName() + " 异步发送完成:messageId: "
+ message.getJMSMessageID() + " " + text);
} catch (JMSException e) {
}
}
});
以及在连接级别也可以设置异步的方式 以及session方式都可以设置改变属性就行
对应添加callback
消息顺序如果使用同一个生产者发送多条消息,则为JMS消息必须满足订购要求。即使已执行同步和异步发送的组合。应用程序是在发送下一条消息之前,无需等待异步发送完成。
在异步发送中 不要去调用close 关闭方法
CompletionListener回调方法不能对其自己的生产者会话调用close
(包括JMSContext)或连接,或在其自己的会话上调用提交或回滚。这样做将
导致关闭、提交或回滚抛出非法状态异常或IllegalStateRuntimeException(取决于方法签名)。
发送有过期时间消息
客户端可以为其发送的每条消息指定生存时间值(以毫秒为单位)。这是用来确定通过添加生存时间值计算的消息过期时间在发送方法上指定到消息发送时(对于事务性发送,这是客户端发送消息的时间,而不是事务提交的时间)。
发送延时消息
客户端可以为其发送的每条消息指定以毫秒为单位的传递延迟值。这是用来确定通过添加传递延迟值计算的邮件传递时间在发送方法上指定到消息发送时(对于事务性发送,这是客户端发送消息的时间,而不是事务提交的时间)。
在源代码中 设置的过期时间
发送更优先的消息 和 设置消息的传递模式
JMS支持两种消息传递模式。
- 非_持久化模式是开销最低的交付模式,因为它没有要求将消息记录到稳定存储器中。JMS提供程序故障可能会导致
- 非永久性消息将丢失。持久化模式指示JMS提供程序格外小心,以确保消息是安全的不会因JMS提供程序故障而在传输过程中丢失。
JMS提供程序最多只能传递一次非_持久消息。这意味着它可能会失败信息,但不能传递两次。
JMS提供程序必须交付一次且仅一次持久性消息。这意味着一个JMS提供者失败不能导致它丢失,也不能两次交付它。
持久(一次且仅一次)和非持久(最多一次)消息传递是一种JMS客户机在交付技术之间进行选择的方法,如果JMS失败,可能会丢失消息提供者死了,而这些提供者需要付出额外的努力来确保消息能够在这种情况下生存失败此选择通常意味着性能/可靠性权衡。当一个客户选择非_持久传递模式,这表示它重视性能而不是性能可靠性选择持久性将反转所请求的权衡。
消息顺序
- 了解消息顺序。默认是时间先后顺序。
- 优先级较高的消息可能会跳到先前优先级较低的消息之前。传递时间较晚的邮件可以在传递时间较早的邮件之后传递时间
- 由于JMS提供程序失败,客户端可能无法接收非_持久消息。如果将持久消息和非持久消息都发送到目标,则顺序仅为保证在交付模式内。也就是说,稍后可能会出现一条非持久消息在较早的持久消息之前;然而,它永远不会提前到达具有相同优先级的非持久消息。
- 客户端可以使用事务处理会话将其发送的消息分组为原子单元(以下简称JMS事务的生产者组件)。事务对特定事务的消息顺序目的地意义重大。跨目的地发送消息的顺序并不重要。
以上是关于JMS解析——JMS简介的主要内容,如果未能解决你的问题,请参考以下文章
JMS Consumer 无法解析 ObjectMessage 中传递的对象的类