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

如何提高jms程序的健壮性

阅读更多
jms api 提供了一下的方式来创建一个健壮的 jms 应用程序

•控制消息的确认方式(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 创建的。

分享到:
评论

相关推荐

    JMS

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

    JMS 简介以及Weblogic配置JMS图解

    通过使用JMS,开发者可以专注于业务逻辑,而不必关心底层的消息传输细节,这极大地提高了代码的可移植性和系统的灵活性。同时,JMS提供的消息持久化和优先级机制确保了消息的重要性和可靠性。在WebLogic这样的应用...

    jms英文书小合集

    6. **分布式系统中的应用**: 在分布式系统中,JMS常用于解耦应用程序组件,提高系统的可扩展性和健壮性。例如,通过消息队列,一个组件可以无阻塞地处理大量请求,而其他组件则在准备好处理这些请求时再从中取出消息...

    jms 2.0规范

    4. **更好的错误处理**:通过引入更灵活的错误处理机制,增强了系统的健壮性。 #### 三、与JMS 1.0.2版本的区别 1. **异步消息处理**:这是JMS 2.0中最具革命性的特性之一。在JMS 1.0.2中,消息消费者需要主动调用...

    JMS经典实例 基于weblogic

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

    Java-JMS实例

    JMS允许开发者在不关心接收方是否在线或能够立即处理消息的情况下发送数据,从而提高系统的可伸缩性和容错性。 **JMS基本概念** 1. **JMS API**:JMS 提供了一组接口和类,使得开发者能够创建、发送、接收和消费...

    消息中间件和JMS原理

    这种方式提高了系统的并行处理能力,增强了系统的可扩展性和健壮性,允许发送方和接收方的生命周期不同步,同时能够实现一对多的消息传递,提高了程序的性能。 JMS(Java Message Service)是由SUN及其合作伙伴提出...

    jms.rar_jms

    Java消息服务(Java Message Service,简称JMS)是Java平台中用于企业级应用间异步通信的一种标准API。它允许应用程序创建、发送、...此外,这也能帮助你了解如何在实际项目中应用JMS来提高系统的可伸缩性和健壮性。

    C#JMS开发

    JMS的主要目标是提高系统的可伸缩性和可靠性,通过解耦发送者和接收者,使得两者不必同时在线即可完成通信。 **二、C#与JMS的结合** 由于JMS是Java的,所以在C#中使用JMS通常需要借助于中间层,如Apache.NMS...

    JMS.rar_answers_jms

    5. **持久性**:JMS允许消息持久化,即使消息生产者和消费者不在同一时间在线,消息也能被保存并稍后传递,增强了系统的健壮性。 6. **事务支持**:JMS提供了事务处理能力,可以确保消息的可靠传递。消息可以在本地...

    jms-1.1接口定义代码

    在实际开发中,JMS常被用于实现微服务间的解耦,提高系统的灵活性和稳定性。例如,通过将任务放入消息队列,后台处理任务的进程可以在负载高峰时保持稳定,避免过载崩溃。 总的来说,JMS 1.1提供了一种标准化的方式...

    JMS 教程 - 消息队列、消息服务

    这种方式不仅降低了客户端之间的耦合度,还极大地提高了系统的可扩展性和健壮性。 #### JMS核心概念及编码实践 JMS提供了一套标准的Java API,用于实现消息的生产、消费以及管理。JMS支持两种主要的消息传递模型:...

    使用jms 操作ActiveMQ

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

    oracle JMS

    - **高可用性与可扩展性**:Oracle AQ具有内置的故障转移机制和负载均衡功能,可以轻松扩展到多服务器环境,从而提高系统的可用性和性能。 - **安全性**:Oracle AQ支持各种安全措施,包括身份验证、授权和加密,以...

    jms配置图解

    总的来说,理解JMS和WebLogic的集成对于构建健壮的企业级应用至关重要,它能帮助你实现异步处理、解耦系统组件以及提高系统的可扩展性和容错性。通过这个资源,你可以深入学习并实践JMS在WebLogic中的应用,从而提升...

    J2EE中的JMS 消息服务

    总结来说,J2EE中的JMS是一个强大的通信机制,它通过解耦生产者和消费者,增强了系统的健壮性和可伸缩性。通过深入理解和熟练运用JMS,开发者可以构建出高效、可靠的分布式应用程序。在实际项目中,配合使用源码和...

    Spring+weblogic9.2发送JMS消息

    5. **异常处理**:为了确保系统的健壮性,你可能还需要配置错误处理策略,如消息重试、死信队列等。 博客文章《Spring+weblogic9.2发送JMS消息》可能详细介绍了上述过程,并可能涉及了实际代码示例和可能遇到的问题...

    一个很好的jms教程

    **JMS(Java Message Service)教程** ...通过深入学习JMS,开发者可以有效地利用消息队列和主题来构建健壮、可扩展的分布式系统。本JMS简明教程将帮助初学者理解其核心概念,并逐步掌握如何在实际项目中运用。

Global site tag (gtag.js) - Google Analytics