2012-03-12 65 views
2

我有一个Spring MDP,使用Spring DefaultMessageListenderContainer监听WebSphere MQ v7.1上的输入队列。如果有错误消息进入(导致RuntimeException),那么当前发生的事情是,事务回滚,并且消息被放回到队列中。然而,MDP进入无限循环。Spring MDP - 如何关闭坏消息

问题1:对于我的要求,我希望能够在看到坏消息的时候关闭处理。不需要重试。是否有可能优雅地关闭消息监听器,以防它看到一个错误的消息(而不是粗糙的System.exit()或那种方法)?我绝对不喜欢它进入无限循环。

编辑:

问题2:有没有办法来停止或暂停监听器容器停止消息的进一步处理?

回答

0

我以下面的方式解决了这个问题,不知道这是否是最好的方法,但它的工作原理。

  1. MDP实现ApplicationContextAware;我也保持一个监听状态(枚举与OPEN,CLOSE,误差值)低于MDP的代码片段:
//context 
private ConfigurableApplicationContext applicationContext; 

//listener state 
private ListenerState listenerState = ListenerState.OPEN; 

@Override 
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
    this.applicationContext = (ConfigurableApplicationContext) applicationContext; 
} 
//onMessage method 
public void processMessages(....) { 
    try { 
    process(...); 
    } catch (Throwable t) { 
    listenerState = ListenerState.ERROR;   
    throw new RuntimeException(...);    
    }  
} 

@Override 
public void stopContext() {   
    applicationContext.stop(); 
} 
  1. 在加载Spring上下文我这样做了Java主:
//check for errors for exit 
    Listener listener = (Listener)context.getBean("listener"); 
    listenerContainer listenerContainer = 
      (ListenerContainer)context.getBean("listenerContainer"); 

    try { 
     while(true) { 
      Thread.sleep(1000); //sleep for 1 sec 
      if(!listener.getListenerState().equals(ListenerState.OPEN)) { 
       listener.stopContext(); 
       listenerContainer.stop(); 
       System.exit(1); 
      }>    }    
    } catch (InterruptedException e) { 
     throw new RuntimeException(e); 
    } 
2

处理这种情况的通常方法是有一个错误队列,并且当你看到一条错误的消息将其放入错误队列时。
某些系统为您处理此问题,例如IBM MQ Series。你只需要配置错误队列以及你想要放置多少次重试。然后
管理员将搜索这些队列,并采取了在队列中的消息适当的措施(即修正并重新提交)

+0

尤其队列的'BOQNAME' ATTR ibute应该包含退出队列的名称,而'BOQTHRESH'应该包含一个大于0的值,它表示在消息被重新发送之前的重试次数。该应用程序必须能够访问目标队列上的'PUT'和'INQ'。如果目标队列不可访问(可能已满或未经授权),则系统DLQ将在下一次尝试。如果'BOTHRESH'设置为零,则不会发生自动重排。 – 2012-03-12 18:23:53

+0

我明白这是标准的方式,这在大多数情况下推荐。但是,就我而言,我不得不停止处理更多的消息。有毒消息停留在输入队列中。我不希望监听器日志继续增长...或者我需要有一个通知机制,并且有人会手动停止监听器。监听器是一个java独立的主,作为一个linux进程启动。 – arrehman 2012-03-12 20:35:11