我正在开发一个EJB,该EJB对其他组件(EJB、Web服务等)进行10多次调用,作为其业务逻辑的一部分。就我而言,性能是一个巨大的问题。这个EJB每天将为几百万个请求提供服务。
我的问题是:对于这10多个调用中的每一个,我如何强制执行超时
等待任何一个调用返回的时间都不能超过'n'秒。如果调用花费的时间超过'n'秒,我将使用默认响应进行处理。
我通常会使用Executor来解决这个问题,但据我所知,不应该从EJB中派生线程,因为它可能会干扰EJB的生命周期。
如何强制超时?
ejb3.1规范提供了使用@AccessTimeout注释设置超时的可能性,该注释适用于当会话Bean实例正忙于执行上一个请求。很明显(规范中描述了明确性),这适用于StateFul和Singleton会话bean,尽管在bean池用完可用实例的情况下,它可以为Stateless实现。请注意,一旦客户端调用的业务方法正在进行中,则不适用此超时。
另一种不属于规范的可能性是在远程客户端定义一个超时,但它得到了多个服务器的支持(参见JBoss示例)。如果客户端调用所花费的时间比配置的超时时间长,客户端将收到通知,但服务器执行不会中断,这还不够好。
设置事务超时也不是一个好的选择,因为无法保证执行业务逻辑的线程在事务超时到期时会被中断。
我通常会使用Executor来解决这个问题,但据我所知,不应该从EJB中派生线程。。
相反,您可以使用ManagedExecutorService类,它是一个适合在EJB容器中使用的Executor扩展。
另外,要在EJB中实现异步调用,请查看@asynchronous注释,它提供了一个高级抽象来解决您面临的多威胁问题。Future类中的Cancel()方法,如果您认为进程花费了太长时间,则可以中断线程的执行。
因为您没有提供环境的太多细节:
- 使用bean管理的事务并设置事务超时
- EE7:提供托管执行器服务
- EE6:作为JCA连接器的自定义执行器服务