如何使用Grails和JMS / ActiveMQ配置独占消费者?

时间:2014-11-30 16:42:51

标签: grails jms activemq spring-jms

我有一个Grails应用程序,它使用JMS插件订阅给定的ActiveMQ主题。如何使TestService类成为独占消费者? Details of exclusive consumer here

用例是我在AWS EC2上运行使用者,并且ActiveMQ订阅源的持久性为5分钟,如果实例死亡则需要更长的时间来替换它。我不能丢失消息并且必须保留消息顺序,因此我希望使用多个实例,其中连接的第一个实例将是代理发送每个消息的实例,而其他实例则保留。在第一个实例死亡的情况下,AMQ代理将消息发送到其他实例之一。

此外,JMS使用什么标准来确定独家消费者何时死亡或消失?

// resources.groovy
beans = {
    jmsConnectionFactory(org.apache.activemq.ActiveMQConnectionFactory) { 
    brokerURL top://example.com:1234 
    userName = 'user' 
    password = 'password' 
    } 
} 

class TestService { 

static exposes = ["jms"] 
static destination = "SOME_TOPIC_NAME" 
static isTopic = true 

def onMessage(msg) { 
    // handle message 

    // explicitly return null to prevent unwanted replyTo attempt 
    return null 
} 

} 

1 个答案:

答案 0 :(得分:0)

首先,您的示例使用的主题不会起作用;你想要队列:

class TestService { 
  static expose = ["jms"] 
  static destination = "MYQUEUE" 
  ...
}

在ActiveMQ中配置独占消费者非常简单:

queue = new ActiveMQQueue("MYQUEUE?consumer.exclusive=true");

..但使用Grails插件可能会很棘手;你可以试试这些:

class TestService { 
  static expose = ["jms"] 
  static destination = "MYQUEUE?consumer.exclusive=true" 
  def onMessage(msg){ ...}
}


class TestService { 
  static expose = ["jms"] 
  @Queue(
     name = "MYQUEUE?consumer.exclusive=true" 
  )
  def handleMessage(msg){ ...}
}

关于代理如何确定消费者是否死亡的问题,我不确定它是如何在ActiveMQ中完成的,但在大多数JMS实现中,TCP故障会在连接上触发异常;对等体(在这种情况下是代理)处理异常并故障转移到下一个可用的消费者。

希望有所帮助