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

如何使用Grails和JMS/ActiveMQ配置独占消费者?,grails,jms,activemq,spring-jms,Grails,Jms,Activemq,Spring Jms,我有一个Grails应用程序,它使用JMS插件订阅给定的ActiveMQ主题。如何使TestService类成为独占消费者 使用案例是,我在AWS EC2上运行消费者,ActiveMQ提要的持久性为5分钟,如果实例死亡,则需要更长的时间来替换它。我不能丢失消息,必须保留消息顺序,因此我希望使用多个实例,其中第一个连接的实例将是代理发送每条消息的实例,而其他实例则保留。在第一个实例死亡的情况下,AMQ代理将向其他实例之一发送消息 此外,JMS使用什么标准来确定独占消费者何时死亡或离开 // res

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

使用案例是,我在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 
} 

} 

首先,您的示例使用了主题,这是行不通的;您需要以下队列:

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故障会触发连接上的异常;对等方(本例中的代理)处理异常并将故障转移到下一个可用的使用者


希望这有帮助

谢谢,我会尝试一下,然后再报告。重新曝光vs曝光,文档上写着“曝光”:对不起,那不行。它需要是一个主题,而不是一个队列,下面是我尝试执行其他操作时的错误消息:“持久订阅需要一个主题(发布子域)”。这是因为我希望能够拥有一个连接持久的独占用户。我的坏消息是关于
expose
,你是对的(我需要放慢阅读文档的速度:-D)。关于耐久性,该功能适用于消息,而不是连接。对于队列,除非代理可以将消息传递给使用者,否则消息将保留在队列上,即period。你说邮件在5百万后过期,你能增加吗?持久订阅价格昂贵,并且有与您的用例相关的严重限制,请参阅,如果可能,请避免使用它们。不,遗憾的是,JMS ActiveMQ提要不在我们公司范围内,消息上只有5分钟的TTL。该服务的目的是获取JMS提要并将其传输到具有更高TTL的RabbitMQ服务中。Raffian是对的,独占消费者仅适用于队列。如果一个主题上有两个消费者,他们每个人都会得到一份消息副本,而这不是你想要的。因此,对非持久消费者使用队列,因为持久消费者只适用于主题(正如Raffian所说,即使没有消费者连接,消息也不会从队列中删除,因此不需要持久订阅的概念)。