技术开发 频道

WebLogic消息服务的运行时管理

【IT168 技术文档】

    随着Internet服务的发展,其分布越来越广泛,这使得企业消息传递逐渐成为Web应用基础架构最重要的部分之一。应用程序可以在短时间内传输大量的消息,而且通常传输的数据是底层的业务流程非常必需的。

    但是,无论这些数据有多么重要,很多企业应用程序的配备不足以使它们在遇到常见的消息传递问题时恢复正常。当然,消息可以保存在数据存储区中,但系统常常缺少可靠且足够灵活的监控和管理机制――像失败消息的适当处理这么重要的功能也可能被忽略掉。

    本文将从管理的角度讨论WebLogic消息传递和Java消息服务(Java Message Service,JMS)。我们将看看如何给予业务关键型消息以应有的关注,以及如何使用管理工具确保应用程序的消息流顺畅无阻。

    企业应用程序中介体

   
企业消息传递基本上全是异构系统间的数据交换,是一种计算机间通信形式,它始终都需要专门的措施以确保其成功运行。如果缺少某种中介体,那么维护跨网络的进程间通信会非常困难,因此我们使用诸如WebLogic JMS之类的面向消息中间件(message-oriented-middleware,MOM)系统来为我们解决保证交付、消息通知以及其他所有的固有复杂问题。可以将MOM视为企业应用程序的邮政服务。

    Weblogic JMS是一种高度可靠的服务,如果它对已发送的消息做出确认,那么用户就完全可以确信该消息已被接收。但是,确切地说,保证就到此为止了;客户端应用程序(消息生产者)无法了解接收端应用程序(消息消费者)是否已成功地处理了该消息,除非用户实现自己的确认系统。

    如果存在问题,那到底是什么问题呢?

    只要两台计算机进行通信,那么迟早会出现故障。无法访问子系统、网络故障、消息溢出、死锁等等,这些全是用户可能遇到的一些常见问题。不要试图保证永远不会发生故障,而是要确保做好应对故障的准备。需要针对每一种处理失败的情况找出其各自的纠正措施。通过自动重试可以很容易地修复某些问题(如:子系统忙),而另外一些问题则需要人工干预。况且,许多服务不支持任何形式的重新处理或错误处理等,这使得故障恢复必须由客户端应用程序来完成。

    我们假设:用户的业务模型将首先使用户尽一切可能处理消息,不行的话才会放弃并向客户端应用程序发出否定确认。在这种情况下,用户可能要自动重试几次处理;若无效,那么应有人能够对失败消息做人工检查。现在来看一种在实践中达成此目的的常见方法。

    消息管理的两种方法

   
一种非常健壮的消息管理技术是将全部的失败消息发送至一个错误队列,并让消费者将其包括的数据和属性保存到一个数据库中。随后,管理员会对该消息进行分析,并选择是否要重新创建消息,然后再次发送。使用数据库来存储消息使得数据具有高度完整性且操作方便。下面是该实现所需的主要步骤:

    1.在config.xml文件中为目的地配置一个持久性错误队列。错误队列又称为死消息队列,失败消息将被自动发送到这个常规JMS目的地。通过在用户的当前目的地(active destination)中添加ErrorDestination参数可将消息定向至错误队列。

    2.为错误队列配置消费者,通过使用javax.jms.Message类的accessor方法使其读取已存储的失败消息的数据和属性。

  3.将恢复性数据与消息的原始目的地名称一起保存到一个数据库表格中。可以通过使用Message类的getJMSDestination()方法获得原始目的地。

  4.编写几个方法,以便从数据库读取数据,显示数据,通过根据已保存的数据重新创建消息、并将其发送至原始目的地,从而提供重新发送消息的选择。

  完成上述步骤后,就可以得到一个非常灵活的管理消息传递问题的系统。该实现需要大量的工作,但是如果用户熟悉JMS并了解其基本知识,那么执行起来就十分简单。虽然这种解决方案非常不错并且经常被使用,但是还有一种更易于实现的方法,它无需使用数据库,并且可以为用户提供额外的好处,即,可以使用户在运行时看到任何队列的内容。

${PageNumber}    用于浏览队列的QueueBrowser

   
JMS API中包括支持全面访问排队消息的工具。下面要讨论的工具是javax.jms.AueueBrowser接口及消息选择器(message selector)。QueueBrowser是一种可在给定队列中检索消息而不消费这些消息的接口。它可返回全部消息,在消息选择器的帮助下还可以返回全部消息的一个子集。

    另一种可供选择的队列管理方法是使用消极错误队列来存储失败消息,并使用QueueBrowser列出这些失败消息。然后可挑选出单个消息,对其进行重新发送、复制或删除操作。  

    下文是关于开发简单的处理失败消息的队列管理系统的分步说明:

    在config.xml文件中为目的地配置持久性错误队列。不需要为错误队列配置或编写任何消费者。

    使用QueueBrowser接口显示错误队列中的全部消息。对队列中消息的浏览非常简单,只需编写几行代码即可实现(见清单)。

    清单1:浏览队列内容

public Enumeration getQueuedMessages(
javax.jms.QueueSession qSession,
javax.jms.Queue queue)
throws javax.jms.JMSException
{
javax.jms.QueueBrowser browser =
qSession.createBrowser(queue);
return browser.getEnumeration();
}

    当用户选择了一条消息后,可使用消息ID作为消息选择器的参数标准来检索该消息(见清单2)。在检索消息后,用户可以很容易地将其重新交付至原始目的地甚至其他的消极队列,以便安全地保管该消息。还可以使用具有相同消息选择器参数的QueueReceiver来删除该消息(见清单3)。用户可在Sun J2EE API文档关于javax.jms.Message接口的部分中找到关于JMS消息选择器的详细介绍。  清单2:获得一个队列中的消息而无需消费它

public javax.jms.Message getMessageFromQueue(
javax.jms.QueueSession qSession,
javax.jms.Queue queue ,String messageId)
throws javax.jms.JMSException
{
javax.jms.QueueBrowser browser =
qSession.createBrowser(
queue, "JMSMessageID = '" + messageId + "'");

return
(javax.jms.Message)
browser.getEnumeration().nextElement();
}

    清单3:通过消费一个消息而从队列中删除它

public void deleteMessageFromQueue(
javax.jms.QueueConnection qConnection,
javax.jms.QueueSession qSession,
javax.jms.Queue queue, String messageId)
throws javax.jms.JMSException
{
javax.jms.QueueReceiver qReceiver =
qSession.createReceiver(
queue, "JMSMessageID = '" + messageId + "'");

qConnection.start();
qReceiver.receive(1000);
}

    在这种方法中,应用容器负责保存用户的消息,从而将用户从繁冗的工作中解放出来。因为一直都在使用JMS Message对象,所以还可免掉许多乏味的数据转换工作。

    为确保一切都达到非常好的状态,请不要忘记使用RedeliveryLimit和RedeliveryDelayOverride参数在config.xml文件中分别设置适当的重发限制与重发时延。

    除开发消息管理系统外,还应考虑构建合适的监控工具来监视目的地。虽然WebLogic控制台可提供所需的大部分统计数据,但仍存在许多原因使得用户应该通过自己的管理系统来获得这些数据――这样可使用户有更多的控制权,况且对生产系统控制台的访问通常会受到限制。

    Java管理扩展(Java Management Extensions,JMX)框架使得服务器统计数据的读取变得非常简单。通过使用JMX,用户可以始终了解服务器的内部运行情况,而JMS正是众多易于通过JMX进行监控的服务之一。

    使用JMX监控JMS目的地

   
WebLogic Server完全支持JMX,这意味着通过JMX可监控几乎全部的WebLogic功能。如果您还没有这样做过,那么打印一份您的服务器上的所有MBean(表示托管资源的JMX对象)的清单,您将惊奇地发现有如此丰富的信息可供使用。下面是一种非常好的办法:用一个单独的进程轮询所有最为关键的MBean,并将所得到的值与预定义的警告等级进行比较。  

    要检索JMS统计数据,首先需要获得希望监控的目的地的JMS MBean,比如weblogic.management.configuration.JMSQueueMBean和weblogic.management.runtime.JMSDestinationRuntimeMBean。这两个类包含若干用来从服务器中查找JMS统计数据的accessor方法。例如,只需指定一些内容,就可以获得目的地所接收的字节总数或当前排队的字节数。若要了解如何获得和使用MBean的详细信息,可查阅WebLogic文档。

    结束语

   
企业消息传递已经无处不在。无论您正在构建哪种服务,不久以后您就很可能需要在其他服务之间或者只是在集群内的进程之间共享数据。JMS是面向这种任务的事实上的行业标准。如果您还不能肯定它的所有优点,请参阅我在WLDJ 1月/2月版中的文章,题目为“Distributing Tasks in a Clustered Environment Using JMS”,您将了解到JMS远远不止是针对异步数据传输。该文章可在WLDJ网站中的Archives部分找到(Vol:4 Iss: 1)。

    无论以何种方式实现企业消息传递,都需要为应对复杂问题做好准备。如果对数据完整性有严格的要求,就请确保进行了适当的监控,并且具有经过认真斟酌的处理消息传递问题(如:消息处理失败)的策略。您可以很方便地获得合适的工具,而且它们都易于使用,因此,当遇到消息传递问题时就没有理由不做好准备了。
0
相关文章