在本文中,我们将详细介绍JMS:JavaMessageService的各个方面,并为您提供关于Java消息服务之一[转]的相关解答,同时,我们也将为您带来关于1,Java消息服务-JMS、Apache
在本文中,我们将详细介绍JMS : Java Message Service 的各个方面,并为您提供关于Java消息服务之一 [转]的相关解答,同时,我们也将为您带来关于1,Java 消息服务 - JMS、Apache Qpid JMS 0.21.0,Java Message Service 客户端、Apache Qpid JMS 0.22.0,Java Message Service 客户端、Apache Qpid JMS 0.23.0,Java Message Service 客户端的有用知识。
本文目录一览:- JMS : Java Message Service (Java消息服务)之一 [转](java messageformat)
- 1,Java 消息服务 - JMS
- Apache Qpid JMS 0.21.0,Java Message Service 客户端
- Apache Qpid JMS 0.22.0,Java Message Service 客户端
- Apache Qpid JMS 0.23.0,Java Message Service 客户端
JMS : Java Message Service (Java消息服务)之一 [转](java messageformat)
1 引言
1.1 编写目的
本文作为B2bi项目中开源产品JORAM的使用指导文档,旨在帮助项目组人员方便明了的进行JMS模块的详细设计和开发工作。本文档主要包含建设银行EAI平台B2Bi子系统中使用的开源JMS产品??JORAM的使用说明
1.2 名词解释
B2Bi:
Business to Business integration (企业间集成)
JMS:
Java Message Service (Java消息服务)
JORAM:
ObjectWeb的Java开源项目
JNDI:
Java命名和目录接口
1.3 参考资料
《Joram-4.3-en.pdf》??JORAM使用手册(英文)
《Joram4_0_SAMPLES.pdf》??JORAM使用举例(英文)
《Joram4_0_ADMIN.pdf》??JORAM管理员手册(英文)
2 JMS简介
2.1 JMS基本概念
JMS(Java Message Service)是访问企业消息系统的标准API,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。
JMS应用由以下几部分组成:
JMS provider :是一个消息系统,它实现了JMS 接口并提供管理和控制的功能。
JMS clients :是用Java语言写的一些程序和组件,它们产生和使用消息。
Messages :是在JMS clients之间传递的消息的对象。
Administered objects :是由使用JMS clients 的人生成的预选设置好的JMS 对象。有两种这样的对象:destinations和connection factories。
2.2 JMS基本功能
JMS是用于和面向消息的中间件相互通信的应用程序接口。它既支持点对点(point-to-point)的域,又支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。
2.3 消息服务类型
1) point-to-point (PTP)方式:点到点的模型。消息由一个JMS客户机(发布者)发送到服务器上的一个目的地,即一个队列(queue)。而另一个JMS客户机(订阅者)则可以访问这个队列,并从该服务器获取这条消息。
point-to-point (PTP)方式有以下特点:
a) 每一个message只有一个使用者。
b) 一个message的sender和receiver没有时间上的依赖关系。无论sendere有没有在运行,Receiver都可提取message。
c) Receiver完成对message处理这后,发出确认。
d) 当你所发出的每一个消息必须由一个使用者成功处理的情况下,使用 PTP messaging机制。
2) publish/subscribe (pub/sub)方式:发布-订阅模型。这里仍然是由一个JMS客户机将一条消息发布到服务器上的一个目的地上,但是这次这个目的地叫做一个主题(topic),可有多个订阅者去访问该消息。消息将一直维持在主题中,直到这个主题的所有订阅者都取走了该消息的一个副本。消息也包括了一个参数,用于定义了该消息的耐久性(它能够在服务器上等待订阅者多长时间)。
Pub/sub messaging有如下的特点:
a) 每一个message可以有多个使用者;
b) Publishers和subscribers在时间上有依赖关系。一个订阅了某一个topic的客户,只能使用在它生成订阅之后发布的message, 并且subscriber必须一直保持活动状态。
c) JMS API允许客户生成持久性的订阅,从而在某种程度上放宽了这种时间上的依赖关系,提高了灵活性处可靠性。
3) Messaging的使用
Messaging本身是异步的,使message的使用者之间没有时间上的依赖关系。但是,JMS规范给出了更精确的定义,使Message可以以两种方式被使用:
a) Synchronously同步:subscriber或receiver可以通过调用receive方法实时地从destination上提取message。Receive方法在收到一个 message后结束,或当message 在一定的时间限制内没有收到时超时结束。
b) Asynchronously异步:客户可以为某一个使用者注册一个message listener。message listener和event listener很相似。当一个message到达了destination, JMS provider通过调用listener的onMessage方法将message传递过去,由onMessage方法负责处理message。
更详细的JMS规范可参考SUN相关文档。
2.4 JMS接口类图
2.5 JMS基本视图
1.JMS接口描述
JMS 支持两种消息类型PTP 和Pub/Sub,分别称作:PTP Domain 和Pub/Sub Domain,这两种接口都继承统一的JMS父接口,JMS 主要接口如下所示:
MS父接口 PTP Pub/Sub
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer QueueReceiver,QueueBrowse r TopicSubscriber
ConnectionFactory :连接工厂,JMS 用它创建连接
Connection :JMS 客户端到JMS Provider 的连接
Destination :消息的目的地
Session: 一个发送或接收消息的线程
MessageProducer: 由Session 对象创建的用来发送消息的对象
MessageConsumer: 由Session 对象创建的用来接收消息的对象
2.JMS消息模型
JMS 消息由以下几部分组成:消息头,属性,消息体。
2.1 消息头(Header) - 消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如:JMSDestination,JMSMessageID 等。
消息头 由谁设置
JMSDestination send 或 publish 方法
JMSDeliveryMode send 或 publish 方法
JMSExpiration send 或 publish 方法
JMSPriority send 或 publish 方法
JMSMessageID send 或 publish 方法
JMSTimestamp send 或 publish 方法
JMSCorrelationID 客户
JMSReplyTo 客户
JMSType 客户
JMSRedelivered JMS Provider
2.2 属性(Properties) - 除了消息头中定义好的标准属性外,JMS 提供一种机制增加新属性到消息头中,这种新属性包含以下几种:
1. 应用需要用到的属性;
2. 消息头中原有的一些可选属性;
3. JMS Provider 需要用到的属性。
标准的JMS 消息头包含以下属性:
JMSDestination 消息发送的目的地
JMSDeliveryMode 传递模式, 有两种模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示该消息一定要被送到目的地,否则会导致应用错误。NON_PERSISTENT 表示偶然丢失该消息是被允许的,这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到平衡点。
JMSMessageID 唯一识别每个消息的标识,由JMS Provider 产生。
JMSTimestamp 一个消息被提交给JMS Provider 到消息被发出的时间。
JMSCorrelationID 用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。
JMSReplyTo 提供本消息回复消息的目的地址
JMSRedelivered 如果一个客户端收到一个设置了JMSRedelivered 属性的消息,则表示可能该客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。
JMSType 消息类型的识别符。
JMSExpiration 消息过期时间,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上发送时刻的GMT 时间值。如果timeToLive值等于零,则JMSExpiration 被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。
JMSPriority 消息优先级,从0-9 十个级别,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。
2.3 消息体(Body) - JMS API 定义了5种消息体格式,也叫消息类型,你可以使用不同形式发送接收数据并可以兼容现有的消息格式,下面描述这5种类型:
消息类型 消息体
TextMessage java.lang.String对象,如xml文件内容
MapMessage 名/值对的集合,名是String对象,值类型可以是Java任何基本类型
BytesMessage 字节流
StreamMessage Java中的输入输出流
ObjectMessage Java中的可序列化对象
Message 没有消息体,只有消息头和属性
下例演示创建并发送一个TextMessage到一个队列:
TextMessage message = queueSession.createTextMessage();
message.setText(msg_text); // msg_text is a String
queueSender.send(message);
下例演示接收消息并转换为合适的消息类型:
Message m = queueReceiver.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}
3. 消息的同步异步接收
消息的同步接收是指客户端主动去接收消息,JMS 客户端可以采用MessageConsumer 的receive方法去接收下一个消息。
消息的异步接收是指当消息到达时,主动通知客户端。JMS 客户端可以通过注册一个实 现MessageListener 接口的对象到MessageConsumer,这样,每当消息到达时,JMS Provider 会调用MessageListener中的onMessage 方法。
4. PTP模型
PTP(Point-to-Point)模型是基于队列的,发送方发消息到队列,接收方从队列接收消息,队列的存在使得消息的异步传输成为可能。和邮件系统中的邮箱一样,队列可以包含各种消息,JMS Provider 提 供工具管理队列的创建、删除。JMS PTP 模型定义了客户端如何向队列发送消息,从队列接收消息,浏览队列中的消息。
下面描述JMS PTP 模型中的主要概念和对象:
名称 描述
Queue 由JMS Provider 管理,队列由队列名识别,客户端可以通过JNDI 接口用队列名得到一个队列对象。
TemporaryQueue 由QueueConnection 创建,而且只能由创建它的QueueConnection 使用。
QueueConnectionFactory 客户端用QueueConnectionFactory 创建QueueConnection 对象。
QueueConnection 一个到JMS PTP provider 的连接,客户端可以用QueueConnection 创建QueueSession 来发送和接收消息。
QueueSession 提供一些方法创建QueueReceiver 、QueueSender、QueueBrowser 和TemporaryQueue。如果在QueueSession 关闭时,有一些消息已经被收到,但还没有被签收(acknowledged),那么,当接收者下次连接到相同的队列时,这些消息还会被再次接收。
QueueReceiver 客户端用QueueReceiver 接收队列中的消息,如果用户在QueueReceiver 中设定了消息选择条件,那么不符合条件的消息会留在队列中,不会被接收到。
QueueSender 客户端用QueueSender 发送消息到队列。
QueueBrowser 客户端可以QueueBrowser 浏览队列中的消息,但不会收走消息。
QueueRequestor JMS 提供QueueRequestor 类简化消息的收发过程。QueueRequestor 的构造函数有两个参数:QueueSession 和queue,QueueRequestor 通过创建一个临时队列来完成最终的收发消息请求。
可靠性(Reliability) 队列可以长久地保存消息直到接收者收到消息。接收者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输模式的优势。
5. PUB/SUB模型
JMS Pub/Sub 模型定义了如何向一个内容节点发布和订阅消息,这些节点被称作主题(topic)。
主题可以被认为是消息的传输中介,发布者(publisher)发布消息到主题,订阅者(subscribe)从主题订阅消息。主题使得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送。
下面描述JMS Pub/Sub 模型中的主要概念和对象:
名称 描述
订阅(subscription) 消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscrip-tion),非持久订阅只有当客户端处于激活状态,也就是和JMS Provider 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向JMS 注册一个识别自己身份的ID,当这个客户端处于离线时,JMS Provider 会为这个ID 保存所有发送到主题的消息,当客户再次连接到JMS Provider时,会根据自己的ID 得到所有当自己处于离线时发送到主题的消息。
Topic 主题由JMS Provider 管理,主题由主题名识别,客户端可以通过JNDI 接口用主题名得到一个主题对象。JMS 没有给出主题的组织和层次结构的定义,由JMS Provider 自己定义。
TemporaryTopic 临时主题由TopicConnection 创建,而且只能由创建它的TopicConnection 使用。临时主题不能提供持久订阅功能。
TopicConnectionFactory 客户端用TopicConnectionFactory 创建TopicConnection 对象。
TopicConnection TopicConnection 是一个到JMS Pub/Sub provider 的连接,客户端可以用TopicConnection创建TopicSession 来发布和订阅消息。
TopicSession TopicSession 提供一些方法创建TopicPublisher、TopicSubscriber、TemporaryTopic 。它还提供unsubscribe 方法取消消息的持久订阅。
TopicPublisher 客户端用TopicPublisher 发布消息到主题。
TopicSubscriber 客户端用TopicSubscriber 接收发布到主题上的消息。可以在TopicSubscriber 中设置消息过滤功能,这样,不符合要求的消息不会被接收。
Durable TopicSubscriber 如果一个客户端需要持久订阅消息,可以使用Durable TopicSubscriber,TopSession 提供一个方法createDurableSubscriber创建Durable TopicSubscriber 对象。
恢复和重新派送(Recovery and Redelivery) 非持久订阅状态下,不能恢复或重新派送一个未签收的消息。只有持久订阅才能恢复或重新派送一个未签收的消息。
TopicRequestor JMS 提供TopicRequestor 类简化消息的收发过程。TopicRequestor 的构造函数有两个参数:TopicSession 和topic。TopicRequestor 通过创建一个临时主题来完成最终的发布和接收消息请求。
可靠性(Reliability) 当所有的消息必须被接收,则用持久订阅模式。当丢失消息能够被容忍,则用非持久订阅模式。
3 JMS API编程模型
一个JMS应用由以下几个模块组成:
3.1 Administered Objects
JMS应用的destinations和connection factories最后是通过管理而不是编程来使用,因为不同的provider使用他们的方法不一样。
JMS 客户应该使用统一的接口得到这些objects,从而使用JMS应用可以运行在不同provider上,而不需要修改或修改很少。通常管理员在JNDI上设置administered objects, 然后JMS clients 在JNDI上look up这些对象。
a) Connection Factories:
connection factory 是client用来生成与provider的connection的对象。connection factory封装了一套由管理员定义的connection configuration参数。每个connection factory 是一个QueueConnectionFactory 或 TopicConnectionFactory接口的实例。
在JMS 客户程序中, 通常先执行connection factory 的JNDI API lookup。 如下例:
Context ctx = new InitialContext();
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) ctx.lookup("TopicConnectionFactory");
如果调用不带参数的InitialContext的lookup方法,就在当前classpath 找jndi.properties文件。
b) Destinations:
Destination 是一个对象用于定义用户产生的messages 的去向或用户使用的messages 的来源。
在PTP里,destinations被称作queues, 可以用下面的命令来生成它们:
Queue queue = (Queue) Queue.create("queue");
在pub/sub里, destinations被称为topics, 可以用下面的J2EE SDK command 来生成它们:
Topic topic = (Topic) Topic.create("topic");
一个JMS应用可以同时使用多个queues 和/或topics。
除了lookup connection factory, 也常要lookup destination。例如:
Topic myTopic = (Topic) ctx.lookup("MyTopic");
Queue myQueue = (Queue) ctx.lookup("MyQueue");
3.2 Connection
Connection封装了一个与JMS provider的虚拟连接。Connection表示在client和provider service daemon之间打开的TCP/IP socket。可以用connection 生成一个或多个sessions。
就象connection factories, connections有两种方式:实现QueueConnection或TopicConnection接口。例如, 当有一个QueueConnectionFactory 或TopicConnectionFactory对象, 可以用他们来创造一个connection:
QueueConnection queueConnection =
queueConnectionFactory.createQueueConnection();
TopicConnection topicConnection =
topicConnectionFactory.createTopicConnection();
注意:当应用程序完成后, 必须关闭你所创建的connections。否则JMS provider 无法释放资源。关闭了connection同时也关闭了sessions和message产生者和message使用者。
queueConnection.close();
topicConnection.close();
在使用messages前, 必须调用connection的start方法。如果要暂时停止传送message而不关闭connection, 可以调用stop方法。
connection factory 是client用来生成与provider的connection的对象。connection factory封装了一套由管理员定义的connection configuration参数。每个connection factory 是一个QueueConnectionFactory 或 TopicConnectionFactory接口的实例。
3.3 Session
Session是单线程的context用于产生和使用messages。用Session创建 message producers、message consumers和messages。Session管理message listeners的执行顺序。
Ssession提供事务模式,用于将一系列的sends和receives动作组合在一个工作单元里。
Session被标记为事务模式的话,确认消息就通过确认和校正来自动地处理。如果session没有标记为事务模式,有三个用于消息确认的选项:
? AUTO_ACKNOWLEDGE session将自动地确认收到一则消息。
? CLIENT_ACKNOWLEDGE 客户端程序将确认收到一则消息,调用这则消息的确认方法。
? DUPS_OK_ACKNOWLEDGE 这个选项命令session“懒散的”确认消息传递,可以想到,这将导致消息提供者传递的一些复制消息可能会出错。这种确认的方式只应当用于消息消费程序可以容忍潜在的副本消息存在的情况。
Sessions, 就象connections, 也有两种方式:实现QueueSession或TopicSession接口。例如:
TopicSession topicSession =
topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
第一个参数表示sessiong不实现事务处理; 第二个参数表示当session成功收到messages后自动确认。
相同的,可以用QueueConnection对象创建QueueSession:
QueueSession queueSession =
queueConnection.createQueueSession(true, 0);
这里, 第一个参数表示session实现事务处理; 第二个参数表示当session成功收到messages后不自动确认。
3.4 Message Producers?消息生产者
message producer是由session创建的一个对象,用于将messages传递到目的地。PTP方式的message producer实现QueueSender接口。 pub/sub方式的message producer实现TopicPublisher接口。
例如::
QueueSender queueSender = queueSession.createSender(myQueue);
TopicPublisher topicPublisher = topicSession.createPublisher(myTopic);
用null作为createSender或createPublisher的参数,可以创建一个不确定的producer。用不确定的producer, 可以等到真正send或publish message的时候才指定destination
当创建了一个message producer, 就可以用它来发送messages。例如:
queueSender.send(message);
topicPublisher.publish(message);
3.5 Message Consumer?消息消费者
message consumer也是由session创建的一个对象,用于接收发送到目的地的消息。message consumer允许JMS client到JMS provider注册感兴趣的目的地。JMS provider管理messages从destination到注册了这个destination的consumers之间的传送。
PTP方式的message consumer实现QueueReceiver接口。pub/sub方式的message consumer实现TopicSubscriber接口。
例如:
QueueReceiver queueReceiver = queueSession.createReceiver(myQueue);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(myTopic);
可以用TopicSession.createDurableSubscriber方法创建一个durable topic subscriber(异步消息订阅 )。
当创建了一个message consumer, 它就是活动的,就可以用它接收messages。可以用QueueReceiver 或TopicSubscriber的close方法把message consumer变成非活动的。Message的传送在调用了connection的start方法后才开始。
不论是QueueReceiver或TopicSubscriber, 都可以用receive方法来同步consume message。可以在调用start方法后的任何时间调用它:
queueConnection.start();
Message m = queueReceiver.receive();
topicConnection.start();
Message m = topicSubscriber.receive(1000); // time out after a second
异步consume message, 可以使用message listener。
a) Message Listeners
message listener是一个对象,用作充当messages的异步事件处理器。它实现了MessageListener接口, 它只有一个方法:onMessage。 在onMessage方法内, 可以定义当收到一个message后做的事情。
用setMessageListener方法在某个QueueReceiver 或TopicSubscriber里注册message listener。例如:
TopicListener topicListener = new TopicListener();
topicSubscriber.setMessageListener(topicListener);
当注册了message listener, 调用QueueConnection或TopicConnection的方法来开始传送message。
当message开始传送, 当有message送来,message consumer自动调用message listener的 onMessage方法。onMessage方法只有一个Message类型的参数。
message listener并不对应特定的destination类型. 相同的listener可以从queue或topic上得到message, 这取决于listener是由QueueReceiver还是 TopicSubscriber对象设置的。然而message listener通常对应某一个message类型或格式, 如果要回应messages, message listener必须创建一个message producer。
onMessage方法应该处理所有的exceptions。
Session负责管理message listeners的执行顺序。任何时候,只有一个message listeners在运行。
b) Message Selectors
如果你的消息应用程序需要过滤收到的messages, 可以用JMS API中的message selector来让message consumer定义它所感兴趣的messages。Message selectors负责过滤到JMS provider的message,而不是到应用程序的。
message selector是一个含有表达式的字符串。表达式的语法是SQL92 conditional expression syntax的一个子集。当创建message consumer时, createReceiver, createSubscriber, 和createDurableSubscriber方法都可以定义某个message selector作为参数。
message consumer只接收headers和properties与selector匹配的messages。message selector不能根据message body的内容进行选择。
3.6 Message?消息组成
JMS 消息由以下几部分组成:消息头,属性,消息体
消息头(Header) - 消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如:JMSDestination,JMSMessageID 等。
消息头 由谁设置
JMSDestination send 或 publish 方法
JMSDeliveryMode send 或 publish 方法
JMSExpiration send 或 publish 方法
JMSPriority send 或 publish 方法
JMSMessageID send 或 publish 方法
JMSTimestamp send 或 publish 方法
JMSCorrelationID 客户
JMSReplyTo 客户
JMSType 客户
JMSRedelivered JMS Provider
属性(Properties) - 除了消息头中定义好的标准属性外,JMS 提供一种机制增加新属性到消息头中,这种新属性包含以下几种:
1. 应用需要用到的属性;
2. 消息头中原有的一些可选属性;
3. JMS Provider 需要用到的属性。
标准的JMS 消息头包含以下属性:
JMSDestination --消息发送的目的地
JMSDeliveryMode --传递模式, 有两种模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示该消息一定要被送到目的地,否则会导致应用错误。NON_PERSISTENT 表示偶然丢失该消息是被允许的,这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到平衡点。
JMSMessageID 唯一识别每个消息的标识,由JMS Provider 产生。
JMSTimestamp 一个消息被提交给JMS Provider 到消息被发出的时间。
JMSCorrelationID 用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。
JMSReplyTo 提供本消息回复消息的目的地址。
JMSRedelivered 如果一个客户端收到一个设置了JMSRedelivered 属性的消息,则表示可能该客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。
JMSType 消息类型的识别符。
JMSExpiration 消息过期时间,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上发送时刻的GMT 时间值。如果timeToLive值等于零,则JMSExpiration 被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。
JMSPriority 消息优先级,从0-9 十个级别,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。
消息体(Body) - JMS API 定义了5种消息体格式,也叫消息类型,你可以使用不同形式发送接收数据并可以兼容现有的消息格式,下面描述这5种类型:
消息类型 消息体
TextMessage java.lang.String对象,如xml文件内容
MapMessage 名/值对的集合,名是String对象,值类型可以是Java任何基本类型
BytesMessage 字节流
StreamMessage Java中的输入输出流
ObjectMessage Java中的可序列化对象
Message 没有消息体,只有消息头和属性。
JMS API为每一种messages都提供了一种create方法。例如:
TextMessage message = queueSession.createTextMessage();
message.setText(msg_text); // msg_text is a String
queueSender.send(message);
在使用者一端, 必须将收到的Message 按照适当的message类型处理。 例如:
Message m = queueReceiver.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}
3.7 Exception Handling
JMS API的方法的Exception的根类是JMSException。JMSException类包括如下子类:
IllegalStateException
InvalidClientIDException
InvalidDestinationException
InvalidSelectorException
JMSSecurityException
MessageEOFException
MessageFormatException
MessageNotReadableException
MessageNotWriteableException
ResourceAllocationException
TransactionInProgressException
TransactionRolledBackException
4 JORAM产品介绍
JORAM是法国电信研究院支持的objectweb.org的开源JMS消息中间件产品。objectweb是一个非常活跃的开源中间件团体。JORAM支持sun规范,实现JMS1.1。
4.1 Joram4.3包括
一个Message Server(消息服务器),提供Java的消息服务功能。
一个JNDI Server。
一个客户端类,可以访问Message Server上的消息。
一个图形化的管理界面,配置管理Joram平台。
4.2 系统要求
硬件要求:
2000年后的intel架构pc机
256M RAM 5G硬盘
支持TCP/IP的网络硬件设备
软件要求:
操作系统:Linux, Windows 2000 and XP, 等
网络协议:TCP/IP
Java运行环境:JDK1.4
4.3 Joram产品包目录结构
doc/ ??Joram产品帮助文档
samples/ ??Joram产品使用举例
bin/... ??Joram例子执行程序
config/... ??Joram例子配置文件
class/... ??Joram例子class文件
run/... ??Joram例子运行目录
src/ ??Joram产品例子源代码
joram/... ??J2EE环境的Joram源代码
kjoram/… ??J2ME环境的Joram源代码
ship/lib/... ??Joram所用的lib包
ship/licenses/... ??Joram的许可证
5 JORAM Classic Samples使用说明
Joram classic samples使用简单的配置创建一个Message Server,发布一个Queue和一个Topic,并允许匿名用户访问。其中包口:一个消息发送的例子、一个消息发布的例子、一个标准的消息生产者的例子、一个消息接收的例子、一个消息订阅的例子、一个标准的消息消费者的例子、一个浏览Queue的例子。Joram平台运行在稳定模式。
可以利用ant工具直接运行Joram的上述例子
起动Joram消息Server:
ant single_server
也可以用命令行启动Joram Server,进入$JoramHome/samples/bin/目录,运行single_server.bat(win)或single_server.sh(unix)。以下操作均有类似的命令行工具。
建立Queue和Topic:
ant classic_admin
运行Sender发送消息例子:
ant sender
运行Receiver接受消息例子:
ant receiver
运行Browser 浏览Queue例子:
ant browser
运行消息订约的例子:
ant subscriber
运行消息发布的例子:
ant publisher
运行消息消费的例子:
ant consumer
运行消息生产的例子:
ant producer
以上操作也可以利用Eclipse3.1集成开发工具,将Joram例子直接导入成Java工程,然后利用例子中的build.xml文件运行。如图:
右击build.xml文件选择Run As ? Ant Build...
弹出窗口如下:每个操作选项后面都有英文的注释信息,说明操作的内容,可以按照前面运行例子的顺序,依次运行即可。
Joram Server也可以通过命令行启动:
进入Joram产品的$JORAM_HOME/samples/bin目录,有下列批处理命令,其中.bat文件是windows环境下的命令,.sh文件是unix环境下的命令。
admin.bat --启动Joram图形控制台界面
admin.sh
classadmin.bat --在启动的Joram Server上创建去queue和topic
clean.bat --清理Joram的运行目录
clean.sh
jmsclient.bat --启动一个JMS客户端
jmsclient.sh
receive.bat --启动一个接收消息进程
send.bat --启动一个发送消息进程
single_server.bat --启动Joram Server
single_server.sh
sslsingle_server.bat
sslsingle_server.sh
server.sh
引文来源 JMS : Java Message Service (Java消息服务)之一 - 采云摘月 - 博客园
1,Java 消息服务 - JMS
一,消息服务
消息服务指的是两个应用程序之间进行异步通信的 API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持应用程序开发。在 Java 中,当两个应用程序使用 JMS 进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务连接起来,可以达到解耦的效果。
二,JMS
2.1,简介
JMS 即 Java 消息服务(Java Message Service)应用程序接口,是一个 Java 平台中关于面向消息中间件(MOM - 分布式系统的集成)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
JMS 是一种与厂商无关的 API,用来访问消息收发系统消息,它类似于 JDBC (Java Database Connectivity)。
2.2,体系架构
JMS 由以下元素组成:
JMS 提供者
连接面向消息中间件的,JMS 接口的一个实现。提供者可以是 Java 平台的 JMS 实现,也可以是非 Java 平台的面向消息中间件的适配器。
JMS 客户
生产或消费基于消息的 Java 的应用程序或对象。
JMS 生产者
创建并发送消息的 JMS 客户。
JMS 消费者
接收消息的 JMS 客户。
JMS 消息
包括可以在 JMS 客户之间传递的数据的对象。
JMS 队列
一个容纳那些被发送的等待阅读的消息的区域。与队列名字所暗示的意思不同,消息的接受顺序并不一定要与消息的发送顺序相同。一旦一个消息被阅读,该消息将被从队列中移走。
JMS 主题
一种支持发送消息给多个订阅者的机制。
2.3,JMS 对象模型
ConnectionFactory
创建 Connection 对象的工厂,针对两种不同的 JMS 消息模型,分别有 QueueConnectionFactory 和 TopicConnectionFactory 两种。可以通过 JNDI 来查找 ConnectionFactory 对象。
Connection
Connection 表示在客户端和 JMS 系统之间建立的链接(对 TCP/IP socket 的包装)。Connection 可以产生一个或多个 Session。跟 ConnectionFactory 一样,Connection 也有两种类型:QueueConnection 和 TopicConnection。
Session
Session 是操作消息的接口。可以通过 session 创建生产者、消费者、消息等。Session 提供了事务的功能。当需要使用 session 发送 / 接收多个消息时,可以将这些发送 / 接收动作放到一个事务中。同样,也分 QueueSession 和 TopicSession。
MessageProducer
消息生产者由 Session 创建,并用于将消息发送到 Destination。同样,消息生产者分两种类型:QueueSender 和 TopicPublisher。可以调用消息生产者的方法(send 或 publish 方法)发送消息。
MessageConsumer
消息消费者由 Session 创建,用于接收被发送到 Destination 的消息。两种类型:QueueReceiver 和 TopicSubscriber。可分别通过 session 的 createReceiver (Queue) 或 createSubscriber (Topic) 来创建。当然,也可以 session 的 creatDurableSubscriber 方法来创建持久化的订阅者。
Destination
Destination 的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的 Destination 是某个队列(Queue)或某个主题(Topic); 对于消息消费者来说,它的 Destination 也是某个队列或主题(即消息来源)。
2.4,JMS 消息模型
在 JMS 标准中,有两种消息模型 PTP(Point to Point),Publish/Subscribe (Pub/Sub)。
2.4.1,PTP 模式 - 点对点消息传送模型
在点对点消息传送模型中,应用程序由消息队列,发送者,接收者组成。每一个消息发送给一个特殊的消息队列,该队列保存了所有发送给它的消息 (除了被接收者消费掉的和过期的消息)。
PTP 的特点
1,每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)。
2,发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列。
3,接收者在成功接收消息之后需向队列发送确认收到通知(acknowledgement)。
2.4.2,Pub/Sub - 发布 / 订阅消息传递模型
在发布 / 订阅消息模型中,发布者发布一个消息,该消息通过 topic 传递给所有的客户端。在这种模型中,发布者和订阅者彼此不知道对方,是匿名的且可以动态发布和订阅 topic。
在发布 / 订阅消息模型中,目的地被称为主题(topic),topic 主要用于保存和传递消息,且会一直保存消息直到消息被传递给客户端。
Pub/Sub 特点
1,每个消息可以有多个消费者。
2,发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个或多个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。
3,为了缓和这样严格的时间相关性,JMS 允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
2.5,接收消息
在 JMS 中,消息的接收可以使用以下两种方式:
同步
使用同步方式接收消息的话,消息订阅者调用 receive () 方法。在 receive () 中,消息未到达或在到达指定时间之前,方法会阻塞,直到消息可用。
异步
使用异步方式接收消息的话,消息订阅者需注册一个消息监听者,类似于事件监听器,只要消息到达,JMS 服务提供者会通过调用监听器的 onMessage () 递送消息。
2.6,JMS 消息结构(Message)
Message 主要由三部分组成,分别是 Header,Properties,Body, 详细如下:
Header
消息头,所有类型的这部分格式都是一样的
Properties
属性,按类型可以分为应用设置的属性,标准属性和消息中间件定义的属性
Body
消息正文,指我们具体需要消息传输的内容。
下面是 Message 接口的部分定义,它显示了 JMS 消息头使用的所有方法:
public interface Message {
public Destination getJMSDestination() throws JMSException;
public void setJMSDestination(Destination destination) throws JMSException;
public int getJMSDeliveryMode() throws JMSException
public void setJMSDeliveryMode(int deliveryMode) throws JMSException;
public String getJMSMessageID() throws JMSException;
public void setJMSMessageID(String id) throws JMSException;
public long getJMSTimestamp() throws JMSException''
public void setJMSTimestamp(long timestamp) throws JMSException;
public long getJMSExpiration() throws JMSException;
public void setJMSExpiration(long expiration) throws JMSException;
public boolean getJMSRedelivered() throws JMSException;
public void setJMSRedelivered(boolean redelivered) throws JMSException;
public int getJMSPriority() throws JMSException;
public void setJMSPriority(int priority) throws JMSException;
public Destination getJMSReplyTo() throws JMSException;
public void setJMSReplyTo(Destination replyTo) throws JMSException;
public String getJMScorrelationID() throws JMSException;
public void setJMSCorrelationID(String correlationID) throws JMSException;
public byte[] getJMSCorrelationIDAsBytes() throws JMSException;
public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException;
public String getJMSType() throws JMSException;
public void setJMSType(String type) throws JMSException;
}
2.6.1,Header
header 中的各个属性,可以分为两大类:
2.6.1.1,自动分配的消息头:
这里这些 JMS 消息头是自动分配的。
在传送消息时,消息头的值由 JMS 提供者来设置,因此开发者使用 setJMSxxx () 方法分配的值就被忽略了。换句话说,对于大多数自动分配的消息头来说,使用赋值函数方法显然是徒劳的。不过,这并非意味着开发者无法控制这些消息头的值。一些自动分配的消息头可以在创建 Session 和 MessageProducer(也就是 TopicPublisher)时,由开发者通过编程方式来设置。
属性名称
说明
设置者
JMSDeliveryMode
消息的发送模式,分为 NON_PERSISTENT 和 PERSISTENT,即非持久性模式的和持久性模式。默认设置为 PERSISTENT(持久性)。
一条持久性消息应该被传送一次(就一次),这就意味着如果 JMS 提供者出现故障,该消息并不会丢失; 它会在服务器恢复正常之后再次传送。
一条非持久性消息最多只会传送一次,这意味着如果 JMS 提供者出现故障,该消息可能会永久丢失。
在持久性和非持久性这两种传送模式中,消息服务器都不会将一条消息向同一消息者发送一次以上(成功算一次)。
// 在消息生产者上设置 JMS 传送模式
TopicPublisher topicPublisher = topicSession.createPublisher(topic);
topicPubiisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
send
JMSMessageID
消息 ID,需要以 ID: 开头,用于唯一地标识了一条消息
send
JMSTimestamp
消息发送时的时间。这条消息头用于确定发送消息和它被消费者实际接收的时间间隔。时间戳是一个以毫秒来计算的 Long 类型时间值(自 1970 年 1 月 1 日算起)。
send
JMSExpiration
消息的过期时间,以毫秒为单位,用来防止把过期的消息传送给消费者。任何直接通过编程方式来调用 setJMSExpiration () 方法都会被忽略。
TopicPublisher topicPublisher = topicSession.createPublisher(topic);
// 将生存时间设置为 1 小时(1000 毫秒 *60 *60)
topicPublisher.setTimeToLive(3600000);
send
JMSRedelivered
消息是否重复发送过,如果该消息之前发送过,那么这个属性的值需要被设置为 true, 客户端可以根据这个属性的值来确认这个消息是否重复发送过,以避免重复处理。
Provider
JMSPriority
消息的优先级,0-4 为普通的优化级,而 5-9 为高优先级,通常情况下,高优化级的消息需要优先发送。任何直接通过编程方式调用 setJMSPriority () 方法都将被忽略。
TopicPublisher topicPublisher = TopicSession.createPublisher(someTopic);
// 设置消息的优先级
topicPublisher.setPriority(9);
send
JMSDestination
消息发送的目的地,是一个 Topic 或 Queue
send
2.6.1.2, 开发者分配的消息头:
属性名称
说明
设置者
JMSCorrelationID
关联的消息 ID,这个通常用在需要回传消息的时候
client
JMSReplyTo
消息回复的目的地,其值为一个 Topic 或 Queue, 这个由发送者设置,但是接收者可以决定是否响应
client
JMSType
由消息发送者设置的消息类型,代表消息的结构,有的消息中间件可能会用到这个,但这个并不是是批消息的种类,比如 TextMessage 之类的
client
从上表中我们可以看到,系统提供的标准头信息一共有 10 个属性,其中有 6 个是由 send 方法在调用时设置的,有三个是由客户端(client)设置的,还有一个是由消息中间件(Provider)设置的。
需要注意的是,这里的客户端(client)不是指消费者,而是指使用 JMS 的客户端,即开发者所写的应用程序,即在生产消息时,这三个属性是可以由应用程序来设定的,而其它的 header 要么由消息中间件设置,要么由发送方法来决定,开发者即使设置了,也是无效的。测试如下:
生产者:
//创建文本消息
TextMessage textMessage = session.createTextMessage("消息内容" + (i + 1 ));
//消息发送的目的地
textMessage.setJMSDestination(new Queue(){
@Override
public String getQueueName() throws JMSException {
return name;
}
});
//消息的发送模式
textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
//消息ID
textMessage.setJMSMessageID("ID:JMSMessageID");
//消息发送时的时间
textMessage.setJMSTimestamp(1000);
//关联的消息ID
textMessage.setJMSCorrelationID("100:JMSCorrelationID");
//消息回复的目的地
textMessage.setJMSReplyTo(new Queue(){
@Override
public String getQueueName() throws JMSException {
return name;
}
});
//消息是否重复发送过
textMessage.setJMSRedelivered(true);
//消息类型,代表消息的结构
textMessage.setJMSType("type");
//消息的过期时间,以毫秒为单位
textMessage.setJMSExpiration(36000);
//消息的优先级,0-4为普通的优化级,而5-9为高优先级
textMessage.setJMSPriority(5);
消费者:
TextMessage msg = (TextMessage) messageConsumer.receive();
//获得消息的发送模式
int jmsDeliveryMode = msg.getJMSDeliveryMode();
//获得消息ID
String jmsMessageID = msg.getJMSMessageID();
//获得消息发送时的时间
Long jmsTimestamp = msg.getJMSTimestamp();
//获得关联的消息ID
String jmsCorrelationID = msg.getJMSCorrelationID();
//获得消息回复的目的地
String jmsReplyTo = ((Queue)msg.getJMSReplyTo()).getQueueName();
//获得消息是否重复发送过
Boolean jmsRedelivered = msg.getJMSRedelivered();
//获得消息类型,代表消息的结构
String jmsType = msg.getJMSType();
//获得消息的过期时间,以毫秒为单位
Long jmsExpiration = msg.getJMSExpiration();
//获得消息的优先级,0-4为普通的优化级,而5-9为高优先级
int jmsPriority = msg.getJMSPriority();
System.out.println("jmsDeliveryMode:" + jmsDeliveryMode);
System.out.println("jmsMessageID:" + jmsMessageID);
System.out.println("jmsTimestamp:" + jmsTimestamp);
System.out.println("jmsCorrelationID:" + jmsCorrelationID);
System.out.println("jmsReplyTo:" + jmsReplyTo);
System.out.println("jmsRedelivered:" + jmsRedelivered);
System.out.println("jmsType:" + jmsType);
System.out.println("jmsExpiration:" + jmsExpiration);
System.out.println("jmsPriority:" + jmsPriority);
System.out.println("----------------------------");
结果:
只有红框的 JmsType,ReplyTo,CorrelationId 可以显示设置,其它设置了都无效。
public interface Message {
public Destination getJMSDestination() throws JMSException;
public void setJMSDestination(Destination destination) throws JMSException;
public int getJMSDeliveryMode() throws JMSException
public void setJMSDeliveryMode(int deliveryMode) throws JMSException;
public String getJMSMessageID() throws JMSException;
public void setJMSMessageID(String id) throws JMSException;
public long getJMSTimestamp() throws JMSException''
public void setJMSTimestamp(long timestamp) throws JMSException;
public long getJMSExpiration() throws JMSException;
public void setJMSExpiration(long expiration) throws JMSException;
public boolean getJMSRedelivered() throws JMSException;
public void setJMSRedelivered(boolean redelivered) throws JMSException;
public int getJMSPriority() throws JMSException;
public void setJMSPriority(int priority) throws JMSException;
public Destination getJMSReplyTo() throws JMSException;
public void setJMSReplyTo(Destination replyTo) throws JMSException;
public String getJMScorrelationID() throws JMSException;
public void setJMSCorrelationID(String correlationID) throws JMSException;
public byte[] getJMSCorrelationIDAsBytes() throws JMSException;
public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException;
public String getJMSType() throws JMSException;
public void setJMSType(String type) throws JMSException;
}
2.6.2,消息属性
消息的属性就像可以分配给一条消息的附加消息头一样。它们允许开发者添加有关消息的不透明附加信息。它们还用于暴露消息选择器在消息过滤时使用的数据。
Message 接口为读取和写入属性提供了若干个取值函数和赋值函数方法。消息的属性值可以是 String, boolean , byte,short, double, int ,long 或 float 型。Message 接口为每种类型的属性值都提供了取值函数和赋值方法。如下:
public interface Message {
public String getStringProperty(String name) throws JMSException,MessageFormatException;
public void setStringProperty(String name,String value) throws JMSException,MessageNotWriteableException;
public int getIntProperty(String name) throws JMSException,MessageFormatException;
public void setIntProperty(String name,int value) throws JMSException,MessageNotWriteableException;
public boolean getBooleanProperty(String name) throws JMSException,MessageFormatException;
public void setBooleanProperty(String name,boolean value) throws JMSException,MessageNotWriteableException;
public double getDoubleProperty(String name) throws JMSException,MessageFormatException;
public void setDoubleProperty(String name) throws JMSException,MessageFormatException;
public float getFloatProperty (String name) throws JMSException,MessageFormatExdeption;
public void setFloatProperty(String name,float value) throws JMSException,MessageNotWriteableException;
public byte getByteProperty(String name) throws JMSException,MessageFormatException;
public void setByteProperty(String name) throws JMSException,MessageNotWriteableException;
public long getLongProperty(String name) throws JMSException,MessageNotWriteableException;
public void setLongProperty(String name,long value) throws JMSException,MessageNotWriteableException;
public short getShortProperty(String name) throws JMSException,MessageFormatException;
public void setShortProperty(String name,short value) throws JMSException,MessageNotWriteableException;
public Object getObjectProperty(String name) throws JMSException,MessageNotWriteableException;
public void setObjectProperty(String name,Object value) throws JMSException,MessageNotWriteableException;
......
}
消息属性有 3 种基本类型:
2.6.2.1,应用程序特定的属性
由应用程序开发者定义的所有属性都可以作为一个应用程序特定的属性。应用程序属性在消息传送之前进行设置。并不存在预先定义的应用程序属性,开发者可以自由定义能够满足它们需要的任何属性。例如,在一个应用中,可以添加一个特定的属性,该属性用于标识正在发送消息的用户:
TextMessage message = pubSession.createTextMessage();
message.setStringProperty("username",username);// 自定义属性
publisher.publish(message);
作为一个应用程序的特定属性,username 一旦离开该应用程序就变得毫无意义,它专门用于应用程序根据发布者身份对消息进行过滤。
一旦一条消息发布或发送以后,它就变成了只读属性;消费者或生产者都无法修改它的属性。如果消费者试图设置某个属性,该方法就会抛出一个 javax.jms.MessageNotWriteableException。
2.6.2.2,JMS 定义的属性
JMS 定义的属性具有和应用程序属性相同的特性,除了前者大多数在消息发送时由 JMS 提供者来设置之外。JMS 定义的属性可以作为可选的 JMS 消息头,下面是 JMS 定义的 9 个属性清单:
JMSXUserID
JMSXAppID
JMSXProducerTXID
JMSXConsumerTXID
JMSXRcvTimestamp
JMSXDeliveryCount
JMSXState
JMSXGroupID
JMSXGroupSeq
在这份清单中,只有 JMSXGroupID 和 JMSXGroupSeq 需要所有 JMS 提供者的支持。这些可选属性用于聚合消息。
请注意:在 Message 接口中,您将无法找到对应的 setJMSX<PROPERTY>() 和 getJMSX<PROPERTY>() 方法定义,在使用这些方法时,必须使用和应用程序特定属性相同的方法来设置它们,如下:
message.setStringProperty("JMSXGroupID","GroupID-001");
message.setIntProperty("JMSXGroupSeq",5);
2.6.2.3,提供者特定的属性
每个 JMS 提供者都可以定义一组私有属性,这些属性可以由客户端或提供者自动设置。提供者特定的属性必须以前缀 JMS 开头,后面紧接着是属性名称(JMS<vendor-property-name>),例如:JMSUserID。提供者特定的属性,其作用就是支持厂商的私有特性。
2.6.3,消息体
为了适应不同场景下的消息,提高消息存储的灵活性,JMS 定义了几种具体类型的消息,不同的子类型的消息体也不一样,需要注意的是,Message 接口并没有提供一个统一的 getBody 之类的方法。消息子接口定义如下:
TextMessage
最简单的消息接口,用于发送文本类的消息,设置 / 获取其 body 的方法定义如下 setText ()/getText ()。
StreamMessage
流式消息接口,里面定义了一系列的对基本类型的 set/get 方法,消息发送者可以通过这些方法写入基本类型的数据,消息接收者需要按发送者的写入顺序来读取相应的数据。
MapMessage
把消息内容存储在 Map 里,本接口定义了一系列对基本类型的的 set/get 方法,与 StreamMessage 不同的是,每个值都对应了一个相应的 key,所以消息接收者不必按顺序去读取数据。
ObjectMessage
将对象作为消息的接口,提供了一个 set/get 对象的方法,需要注意的是只能设置一个对象,这个对象可以是一个 Collection,但必须是序列化的。
BytesMessage
以字节的形式来传递消息的接口,除了提供了对基本类型的 set/get,还提供了按字节方式进行 set/get。
Apache Qpid JMS 0.21.0,Java Message Service 客户端
Apache Qpid JMS 0.21.0 发布了,Qpid JMS 是一个使用 Qpid Proton 协议引擎的 Java Message Service 客户端。
该版本支持 Advanced Message Queuing Protocol 1.0 (AMQP 1.0, ISO/IEC 19464,http://www.amqp.org)。
新特性和改进:
QPIDJMS-244 - Connection close does not wait for acknowledgement of in-flight message delivery with asyncronous auto-ack MessageConsumer
QPIDJMS-258 - Reduce the amount of allocation done in the consumer on async message dispatch
QPIDJMS-267 - Support discovery of failover hosts provided in a connection property of the Open frame
QPIDJMS-270 - update to proton-j 0.18.0
QPIDJMS-271 - Cache transaction state dispostions for TXN producers and consumers
Bug 修复
QPIDJMS-231 - closing a consumer used since prior commit/rollback holds its prefetched messages until the next commit/rollback
QPIDJMS-256 - Closing a consumer that was used in a transaction does not stop message dispatching unitl next commit or rollback
QPIDJMS-257 - Messages delivered from a consume in client acknowledge mode cannot be acknowledged after the consumer is closed
QPIDJMS-266 - Race on session start and message dispatch can deliver messages in wrong order
QPIDJMS-269 - Performance regression affecting MessageProducer on transacted Sessions.
QPIDJMS-272 - fail fast when attempting connection to a server using unexpected protocol type
Tasks
QPIDJMS-262 - Update ActiveMQ Dependency to latest 5.14.3
QPIDJMS-268 - Update Netty to 4.1.8.Final
下载地址 和 发布日志
Apache Qpid JMS 0.22.0,Java Message Service 客户端
Apache Qpid JMS 0.22.0 发布了,Qpid JMS 是一个使用 Qpid Proton 协议引擎的 Java Message Service 客户端。
这是最新的 JMS 客户端,支持基于 Apache Qpid Proton 协议引擎的高级消息队列协议 1.0(AMQP 1.0, ISO/IEC 19464, http://www.amqp.org),并实现了 AMQP JMS 映射在 OASIS 的发展。
更新如下:
新特性和改进
QPIDJMS-274 - Be able to REJECT messages in JmsRedeliveryPolicy
QPIDJMS-278 - Add a fast path for the Accepted outcome into the producer
QPIDJMS-279 - Add support for Netty Epoll transport
QPIDJMS-281 - Add option to the transport to allow for tracing bytes in / out in the logs
QPIDJMS-283 - Pipeline the declare that follows a transaction discharge for quicker processing
QPIDJMS-285 - Throw a more meaningful exception when commit fails due to connection being down
QPIDJMS-286 - Shorten the thread name given to the AmqpProvider executor thread
Bug 修复
QPIDJMS-282 - creating a Connection can time out if a pipelined Open frame arrives before the client sends its own
QPIDJMS-284 - client includes ''global'' source capability for some consumers it shouldn''t
Tasks
QPIDJMS-275 - Update Netty to latest release
QPIDJMS-276 - Update slf4j to latest release
下载地址,二进制文件
发布说明
Apache Qpid JMS 0.23.0,Java Message Service 客户端
Apache Qpid JMS 0.23.0 发布了,Qpid JMS 是一个使用 Qpid Proton 协议引擎的 Java Message Service 客户端。
这是最新的 JMS 客户端,支持基于 Apache Qpid Proton 协议引擎的高级消息队列协议 1.0(AMQP 1.0, ISO/IEC 19464, http://www.amqp.org),并实现了 AMQP JMS 映射在 OASIS 的发展。
新特性和改进
QPIDJMS-291 - 升级至 proton-j 0.19.0
Bugs 修复
QPIDJMS-288 - 连接执行器在连接失败时不关闭
QPIDJMS-289 - 即使在发送期间没有传送延迟,也应填充 JMSDeliveryTime
QPIDJMS-290 - [Websocket] 解码器接收字节消息超过 65347 字节的内容时失败
QPIDJMS-292 - 消费者可能会比预期的 “预取” 值缓冲更多的消息
下载地址和二进制文件
发布说明和发布主页
我们今天的关于JMS : Java Message Service 和Java消息服务之一 [转]的分享就到这里,谢谢您的阅读,如果想了解更多关于1,Java 消息服务 - JMS、Apache Qpid JMS 0.21.0,Java Message Service 客户端、Apache Qpid JMS 0.22.0,Java Message Service 客户端、Apache Qpid JMS 0.23.0,Java Message Service 客户端的相关信息,可以在本站进行搜索。
本文标签: