使用JMS在集群应用程序中分配任务(图)
让我们逐个看看这个框架的所有部分:
JMS 队列 : 应该在每台服务器上配置一个用于接收命令消息的 JMS 队列。还应该为重复保存故障消息配置错误队列。
JMS 连接工厂 : 为了支持事务性行为的运行时选择,应该配置两个连接工厂:一个支持 XA ,而另一个不支持 XA 。
命令对象接口 (CommandMessage) : 这是一个所有命令对象都需要实现的简单 Java 接口。它扩展了 java.io.Serializable 接口,该接口对于在 JMS 对象消息中嵌入我们的命令来说是必需的。现在,因为我们想要在不知道命令的确切类型的情况下运行它们,我们还要实现 java.lang.Runnable 接口,稍后把它们简单地转换为 Runnable 对象,并执行它们的运行方法。我们在不知道我们运行的确切内容的情况下运行了代码。这是最理想的多态。
命令执行程序 (CommandExecutionManager) : 我们将使用一个 MDB 来处理命令。实例池化防止了 JMS 初始化重复出现,这使得 MDB 成为功能非常强大的消息监听器,非常适合于这项任务。编写 Bean 类不需要很大的工作量,我们只需要在 onMessage 方法中编写数行代码(参见清单 1 )。
这样就把收到的消息传递给一个 ObjectMessage ,获得嵌入的命令对象,然后执行它的运行方法。通过在 config.xml 文件中,把队列的重新发送限制设置为一个大于 0 的值,您可以配置一个重试计数器。从您的命令对象抛出一个运行时异常,便可触发重新发送的动作。此外,通过配置重新发送延迟,您还可以控制重试的频率。
用于发送消息的一个帮助器类 (TaskDistributor)
从技术上说,这个部分并不是完全必要的,每次都可以手动进行 JMS 排队。然而,这是一个冗长乏味的过程,而且实际上是帮助器使这个框架变得如此实用。帮助器是一个常规的 Java 类,带有用于对命令消息进行排队的静态方法。您可以针对处理不同的场景编写单独的方法,但是为了简明起见,我选择了编写一个可以处理大多数情况的方法:
static void execute(CommandMessage cm, long delay, b oo lean runEverywhere, b oo lean persisted, b oo lean
enableXA, int priority)
这个静态方法带有几个用于精确执行控制的参数。让我们逐个讨论这些参数:
CommandMessage cm : 一个命令消息实例。
long delay : 代表发送属性的时间,借助 weblogic.jms.extensions.WLMessageProducer 类进行设置。这样,就可以在夜间或者其他方便的时间执行命令。接受一个 Date 对象也是可以的。
b oo lean runEverywhere : 决定是否发送要执行的消息给集群中的一台随机选中的访问器或者所有的服务器。
b oo lean persisted : 将通过使用队列发送程序的 setDeliveryMode 方法选择发送模式。应该始终保持业务关键型的消息,从而在访问器崩溃的时候,这些消息不会丢失。然而,持久性始终是以性能损失为代价的,这也应该纳入考虑的范围内。
b oo lean enableXA : 将选择方法是否使用支持 XA 的 JMS 连接工厂。此参数设置为 true 时,排队将参与底层事务(如果存在的话),在提交事务之前不会对消息进行排队。
int priority : 决定消息的 JMS 优先级。在发送之前,将使用给定的值调用 javax.jms.Message 类的 setJMSPriority 方法。有效的范围是 0-9 。对于大多数应用程序来说,给命令消息指派不同的优先级似乎有些过头,但是出于完整性方面的考虑,我还是在这里包括了这个选择。
应该针对您的特定执行的需要,来量身打造 TaskDistributor 帮助器类的实现。在本文中,要包含一个例子似乎太长了,但是您可以从 WLDJ Web 站点 www.sys-con.