Jakarta ee 消息驱动bean,并在指数后退的情况下重试

Jakarta ee 消息驱动bean,并在指数后退的情况下重试,jakarta-ee,jms,message-driven-bean,Jakarta Ee,Jms,Message Driven Bean,我有一个要求,若我从消息驱动bean调用的服务(Restful服务)关闭或未返回成功,我需要将消息回滚到队列,等待一段时间(指数),然后再次从队列读取消息并尝试连接到服务 我正在尝试的是: 在OnMessage方法中,如果我从调用Restful服务的服务接收到异常,我将使用messageDrivenContext.setRollBackOnly()回滚,我可以执行类似Thread.sleep(重试等待时间) 但是我如何确保重试\u等待\u时间呈指数增长 可能我需要维护bean的状态,但是有人能建

我有一个要求,若我从消息驱动bean调用的服务(Restful服务)关闭或未返回成功,我需要将消息回滚到队列,等待一段时间(指数),然后再次从队列读取消息并尝试连接到服务

我正在尝试的是:

OnMessage
方法中,如果我从调用Restful服务的服务接收到异常,我将使用
messageDrivenContext.setRollBackOnly()
回滚,我可以执行类似
Thread.sleep(重试等待时间)

但是我如何确保
重试\u等待\u时间
呈指数增长


可能我需要维护bean的状态,但是有人能建议我怎么做吗?

根据您的设置,有多种方法可以实现这一点。如果所有消息都将调用相同的服务,则可以在MDB上下文中定义一个全局调节参数,该参数定义让MDB睡眠的时间。您可以使用基本的指数延迟,例如:

final int throttleTime = 60;  //Assume we delay 60 sec before retry
int throttle = 1;

private int getThrottle(){
  throttle = throttleTime * throttle;
  return throttle;
}

private void resetThrottle(){
  throttle = 1;
}

public void onMessage(Message message){
  try{
     service.invoke();
  } catch (InvocationException e) {
    try{
      Thread.sleep(getThrottle()*1000);
      onMessage(message);
    } catch (InterruptedException e) {
      logger.error(e.getMessage());
    }
  } finally {    
    resetThrottle();
  }
}       

注意当MDB向容器抛出异常时,一些应用服务器已经逐渐增加了读取消息的重试时间。同样,一些排队系统允许配置让消息在队列中的某个时间出现。检查您的基础架构的规范在该主题中描述了什么

我将首先研究您正在使用的任何消息队列的配置选项,以查看它是否没有此类特定的重新传递设置。我会让你的生活变得轻松,而不是要求时间间隔是指数级的。如果您偏离了标准,您将进入自己的领域,而不是使用MDB,而是使用手动构建的消息客户端。在Java EE环境中使用
Thread.sleep()
,这是一种危险的行为,规范严重禁止。感谢Filip的回复。是的,在我的情况下,所有消息都将调用相同的服务,我已经在websphere中配置了10个MDB实例。请告诉我在哪里设置全局节流参数以及如何实现指数延迟。。。