`
jerrycong
  • 浏览: 21533 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

创建健壮的 jms 应用程序(jms QoS)

阅读更多
转载自其它网站


jms 在 api 级别提供了以下几种提高程序可靠性的方式:

    * 控制消息的确认方式(acknowledgment)
    * 配置消息的持久性(确保当 jms 提供者失败时,消息不会丢失)
    * 设置消息的优先级(影响消息传递的顺序)
    * 允许消息过期(设置消息的过期时间,这样消息过期后 jms provider 就会丢弃此消息)
    * 创建临时目的地(临时目的会在创建它的连接被关闭时被销毁)
    * 创建持久订阅
    * 使用本地事务

控制消息确认方式

如果一条消息没有被确认,那么 jms provider 会认为此消息没有成功地被消费。一条消息成功地被客户端消费通常包含3个步骤:

   1. 客户端接收到这条消息
   2. 客户端成功处理这条消息
   3. 客户端确认这条消息

消息的确认是由 jms provider 触发还是由客户端触发,这取决于会话的确认模式。

在事务性会话中,事务提交的时候会自动确认消息,当事务被回滚,所有消费的消息都会被重传。

在非事务性会话中,什么时候以及如何确认消息取决于 createQueueSession 、 createTopicSession 和 createSession 方法的第二个参数的取值。有三种可选的取值:

    * Session.AUTO_ACKNOWLEDGE    会话自动确认。当客户端调用 receive 方法并成功返回以及调用 MessageListener 处理消息并成功返回后,会话会自动确认已成功接收到消息。在 AUTO_ACKNOWLEDGET 会话中,同步接收消息是一个例外(消费一条消息包含三个步骤),在这种情况下,消息接收和确认在同一个步骤中发生。
    * Session.CLIENT_ACKNOWLEDGE    客户端确认。客户端通过调用消息的 acknowledge 方法手动确认成功接收一条消息。在这种模式下,消息确认发生在会话级别,确认一条消息会自动确认由此会话消费的所有消息。例如,一个消费者消费10条消 息,并在消费第5条消息的时候调用了 acknowledge 方法,这会确认所有的10条消息。
    * Session.DUPS_OK_ACKNOWLEDGE    这个选项会使会话延迟消息的确认。在消息传递过程中,如果 jms provider 失败,这可能会导致传递一些重复的消息,因此只有在消费者允许重复的消息时才考虑使用此模式(如果重传一条消息,jms provider 必须设置消息头 JMSRedelivered 为 true)。

当 QueueSession 被关闭,jms provider 会保持那些客户端已经接受到但还没有确认的消息,并在下一次客户端连接到队列的时候重传这些消息。同样,当 TopicSession 关闭,jms provider 也会保持那些持久 TopicSubcriber 没有确认的消息。非持久 TopicSubscriber 没有确认的消息,当会话关闭时会被丢弃。

如果使用队列和持久订阅,可以调用方法 Session.recover 使会话停止当前消息传递,并从第一个没有确认的消息开始重新传递,这会使消息传递的顺序与消息发送的顺序不一致。对于非持久订阅的 TopicSubscriber,当恢复会话时 jms provider 可能会丢弃没有确认的消息。

设置消息的持久性

jms 提供了两种消息传递模式,这两种模式决定了当 jms provider 失败时消息是否会丢失。DeliveryMode 接口提供了这两种传递模式。

PERSISTENT 传递模式要求 jms provider 确保在消息传输过程中如果 jms provider 失败消息不会丢失,这是默认的传输模式。使用这种模式发送的消息在发送的时候会被记录到一个持久储存中。

NON_PERSISTENT 传递模式不要求 jms provider 把消息保存到持久存储中,同样也不保证如果 jms provider 失败,消息不会丢失。

有两种方式设置消息传递模式:

   1. 调用 MessageProducer 的 setDelieryMode 方法设置传递模式,此 MessageProducer 发送的消息都使用这个方法设置的传递模式。
   2. 使用重载的 send 和 publish 方法设置特定消息的传递模式

如果不指定传递模式,默认使用 PERSISTENT 模式。使用 NON_PERSISTENT 可以提高性能以及降低存储需求。

设置消息优先级

可以使用优先级使 jms provider 优先传递紧急的消息。有两种方式设置消息优先级。

   1. 调用 MessageProducer 的 setPriority 方法设置此 MessageProducer 发送的消息的优先级
   2. 调用重载的 send 和 publish 方法为特殊的消息设置优先级

消息的优先级从0(最低)到9(最高)有10种级别。如果没有设置优先级,默认优先级为4。jms provider 会确保优先级高的消息会在优先级低的消息之前被传递,但并不保证会严格按照优先级的顺序来传递消息。

允许消息过期

默认情况下,消息永远不会过期。但如果一条消息在一段时间之后就会被废弃,那么可以设置消息的过期时间。有两种方式可以设置消息的过期时间。

   1. 调用 MessageProducer 的 setTimeToLive 设置 MessageProducer 发送的消息的默认过期时间
   2. 使用重载的 send 和 publish 方法设置特定消息的过期时间

如果设置 timeToLive 为0,那么消息永远不会过期。

发送消息时,会使用当前时间与 timeToLive 的和设置消息的过期时间。任何在指定的过期时间之前没有被传递的消息都会被销毁。

创建临时目的

jms 提供了方法 QueueSession.createTemporaryQueue 和 TopicSession.createTemporaryTopic 来创建临时队列 TemporaryQueue 和临时主题 TemporaryTopic,临时目的在创建它们的连接被关闭时会被销毁。

仅有使用创建临时目的的连接创建的消费者才能消费临时目的上的消息,但任何一个消息生产者都可以向临时目的上发送消息。如果关闭创建临时目的地连接,那么临时目的也会被关闭,临时目的上的消息会丢失。

创建持久订阅

为了确保发布/订阅应用程序能够接收到所有已发布的消息,在发布端可以使用 PERSISTENT 传递模式传输消息以确保消息不回在传输过程中丢失,而在订阅端则可以使用持久订阅来保证能够收到所有已发布的消息。

TopicSession.createSubscriber 方法创建一个非持久订阅者。非持久订阅者只能接收到在它处于活动状态时发布的消息。

可以使用方法 TopicSession.createDurableSubscriber 创建一个持久订阅者。持久订阅在任何时候仅能有一个订阅者。

一 个持久订阅者使用一个由 jms provider 维护的唯一的标识符注册一个持久订阅。随后的订阅者会恢复之前订阅者在关闭之前的状态。如果一个持久订阅没有处于活动状态的订阅者,jms provider 会保持订阅的消息直到这些消息被订阅者接收到或者消息过期。

使用如下设置能够创建一个持久订阅的唯一标识符:

    * 为连接设置一个唯一的客户 id( Connection.setClientID )
    * 订阅的主题名以及订阅的名称

创 建了一个连接并设置了其客户 id 之后,可以使用连接创建 Session,并调用这个 Session 的 createDurableSubscriber 来创建一个持久订阅者,这个方法接收两个参数,第一个参数是一个主题名,第二个参数是创建的这个持久订阅的名称,例如:

String topicName = "myTopic";
String subName = "mySub";
TopicSubscriber sub = topicSession.createDurableSubscriber( topicName, subName );

调用 TopicConnection 的 start 方法后此订阅者就处于活动状态。这之后可以关闭此 TopicSubscriber:

            topicSubscriber.close();

jms provider 会保存发布到这个主题上的消息。如果任意一个应用程序使用具有相同客户 id 的连接,并使用相同的主题和订阅名调用 createDurableSubscriber 方法,那么这个持久订阅就会被激活,jms provider 就会把在此订阅者处于不活动状态发布的消息传递给此订阅者。

删除一个持久订阅,首先要关闭订阅者,然后使用订阅名调用 unsubscribe 方法注销持久订阅。

            topicSubscriber.close();
                  topicSession.unsubscribe( "mySub" );

unsubscribe 方法会使 jms provder 删除它维护的关于订阅者的状态信息。

使用本地事务

可以把一系列操作组成一个称为事务的原子工作单元。如果一个操作失败,事务会被回滚,并可以尝试重新执行这一组操作。如果这一组操作都成功,事务则会被提交。

jms 客户端可以在事务中发送和接受一组消息。jms api 中的 Session 接口提供了 commit 和 rollback 方法来提交回滚事务。事务提交意味着生产的所有消息都会被发送,消费的所有消息都会被确认。事务回滚意味着生产的消息都会被销毁,消费的消息都会被重传直 到它们过期。

一个事务性会话始终包含在一个事务中。只要调用了 commit 方法或 rollback 方法,这意味着一个事务的结束,新的事务的开始。关闭事务性会话会回滚正在进行的事务。

当 创建会话的时候可以指定会话是否为事务性的。方法 createQueueSession 与 createTopicSession 的第一个参数是一个 boolean 类型的,如果设为 true 则新建的会话为事务性的,如果为 false 新建的回话则不是事务性的。这两个方法的第二个参数是设置确认模式的,这个值只有在非事务性回话中有效,事务性会话则会忽略确认模式,所以可以设置为0, 例如:

            topicSession = topicConnection.createTopicSession( true, 0 );

由 于本地事务的提交与回滚是与回话相关联的,所以不能把对队列的主题的操作绑定到同一个事务中。因为 QueueReceiver、QueueSender 与 TopicSubscriber、TopicPublisher 分别是由 QueueSession 和 TopicSession 创建的。
分享到:
评论

相关推荐

    .net 动态创建应用程序域和卸载应用程序域

    本文将深入探讨如何动态创建应用程序域以及如何卸载应用程序域,特别是在插件模式下的应用。 ### 一、应用程序域的基本概念 1. **安全隔离**:每个应用程序域都有自己的安全策略,可以限制代码的访问权限,防止...

    论文研究-嵌入式Linux应用程序健壮性研究 .pdf

    总结来说,这篇关于嵌入式Linux应用程序健壮性研究的文档,不仅介绍了相关概念和意义,还提出了提高应用程序健壮性的几种可能方案,并强调了守护进程在其中的关键作用。这些知识点对于从事嵌入式系统开发的工程师和...

    应用程序的创建与撤销

    在创建应用程序时,我们需要考虑编程语言的选择,例如Java,Python,C#或JavaScript等,每种语言都有其适用场景和优缺点。同时,现代开发常常采用敏捷开发方法,如Scrum或Kanban,以提高效率并快速响应变化。 在...

    JMS经典实例 基于weblogic

    总的来说,JMS与WebLogic的结合提供了强大的消息传递能力,使得开发者能够构建健壮、灵活的分布式应用程序。无论是简单的工作队列还是复杂的发布/订阅模式,JMS都能提供可靠的解决方案。通过深入理解和熟练运用JMS,...

    使用jms 操作ActiveMQ

    总之,掌握JMS与ActiveMQ的结合使用,能帮助你构建高效、健壮的分布式系统,实现应用程序间的异步通信,提升系统的灵活性和可靠性。通过不断学习和实践,你将能够熟练地在各种场景下应用这些技术。

    JMS 简介以及Weblogic配置JMS图解

    JMS提供了一种与平台无关的方式,使得应用程序可以与各种消息中间件提供商进行交互,就像JDBC允许Java应用程序连接到多种类型的数据库一样。 **JMS的核心概念** 1. **JMS提供者**:这是实现JMS接口的服务,负责...

    C#创建多线程应用程序

    在C#编程中,创建多线程应用程序是提高程序性能和响应能力的一种有效方式。多线程使得程序能够同时执行多个任务,从而更好地利用多核处理器的计算能力。本篇文章将深入探讨C#中如何创建和管理多线程,以及涉及的相关...

    Weblogic环境下JMS配置

    5. 部署JMS资源:将创建的JMS资源部署到WebLogic域中,以便应用程序能够使用它们。 6. 编写应用程序代码:在Java代码中,我们需要使用JMS API来发送和接收消息。例如,使用`ConnectionFactory`创建连接,然后创建...

    javax包下的javax.jms.jar及servlet-api.jar

    **Java消息服务(JMS)**是Java平台上的一个标准接口,它允许应用程序创建、发送、接收和读取消息。`javax.jms`包提供了与消息传递系统交互所需的接口和类。JMS主要应用于分布式环境中的异步通信,它支持点对点...

    c#窗体应用程序实例

    在C#编程领域,窗体应用程序(Windows Forms)是创建桌面应用的基本框架,它为开发者提供了丰富的用户界面组件和事件处理机制。这个“c#窗体应用程序实例”压缩包很显然是一个面向C#初学者的教学资源,包含了多个...

    jms英文书小合集

    **Java消息服务(Java Message Service,简称JMS)**是一种标准的应用程序接口(API),它允许应用程序在分布式环境中创建、发送、接收和读取消息。JMS被设计用来解决应用程序之间的异步通信问题,它是Java平台上的...

    activeMQ JMS 3种创建方式

    JMX允许管理员远程管理和监控Java应用程序,包括ActiveMQ。通过JMX,可以创建和管理QUEUE和TOPIC。 1. 连接JMX:使用JConsole或JMX Console等工具连接到运行中的ActiveMQ服务器。 2. 查找MBean:在MBean浏览器中...

    ActiveMQ 中javax.jms的源码 javax.jms-sources-1.1.zip

    首先,javax.jms是一个Java API,它提供了一组与消息传递平台无关的接口,使得开发者能够创建可靠的异步通信应用程序。该API主要包含以下组件: 1. **Message**:消息接口是所有JMS消息的基类,它封装了要传输的...

    应用openJMS实现JMS消息发布于订阅

    同时,理解JMS事务、消息优先级和持久性等高级特性,对于构建健壮的应用程序也非常重要。总的来说,OpenJMS作为开源的JMS实现,为Java开发者提供了强大的消息传递功能,是构建分布式系统和微服务架构时的重要工具。

    Java-JMS实例

    JMS在Java应用程序和企业级系统集成中扮演着重要角色,它提供了一种健壮且灵活的通信机制。通过WebLogic JMS Server,开发者可以构建高可用、高性能的分布式系统,确保数据的可靠传输,同时降低系统间的耦合度。在...

    jms-study.zip_jms_server jms

    JMS允许应用程序创建、发送、接收和读取消息,它是企业系统间解耦和异步通信的关键工具。 在JMS中,主要有两个核心概念:消息生产者和消息消费者。消息生产者创建并发送消息,而消息消费者则接收这些消息。两者之间...

    JMS

    开发者可以利用JMS来解耦应用程序组件,提高系统的可扩展性和可靠性。通过将数据封装成消息并发送到队列或主题,发送方与接收方无需同时在线,提高了系统的灵活性。在给出的博客链接中,可能包含了关于如何使用JMS,...

    jms配置图解

    WebLogic Server,作为Oracle公司的企业级Java应用服务器,支持JMS服务,允许开发者构建高可用、可扩展且异步处理的分布式应用程序。 在"jms配置图解"的资源中,你将找到如何在WebLogic环境中配置JMS服务的详细步骤...

    Java理论与实践: 应该在下一个企业应用程序中使用JMS吗?

    在企业级应用程序中,JMS通常用于提高系统的可扩展性和灵活性,因为它允许应用程序在不直接互相依赖的情况下交换数据。这种解耦特性是通过消息队列实现的,其中消息生产者发送消息到队列,而消费者则在准备好处理时...

Global site tag (gtag.js) - Google Analytics