在Java / Groovy中重试的反应事件处理

时间:2014-05-25 18:15:54

标签: java events actor reactive-programming

我想实现一个微服务,它在收到请求后(通过消息队列)将尝试通过对外部服务的REST / SOAP调用来执行它。成功时,回复应该通过MQ发回,但失败请求重新安排以便稍后执行(使用一些自定义算法,如10秒,1分钟,10分钟,超时 - 放弃)。在指定的时间后,应将失败消息发送回请求者。

它应该在Java 8和/或Groovy上运行。事件持久性是必需的。

首先我虽然关于ExecutorRunnable/Future以及ScheduledExecutorService.scheduleWithFixedDelay,但它对我来说看起来很低。第二个想法是有AkkaScheduler(重新安排)的演员,但我确信可能还有其他方法。

问题即可。您可以使用什么技术进行反应事件处理,并能够在失败时重新安排它们?

3 个答案:

答案 0 :(得分:0)

“事件”是一个相当模糊的术语,但我遇到的大多数定义都是谈论控制反转技术之一。这一个的特点是事实,你不关心WHEN和BY WHOM一些代码将被调用,但在什么条件。这意味着您可以反转(或更精确地“丢失”)对执行流程的控制。

现在,您需要事件驱动的处理(因此您不想处理WHEN和BY WHOM),但是您希望在失败时指定TIMED(严格连接到WHEN)行为。这对我来说是一种悖论。

我会说你会做得更好,如果你使用回调进行反应式编程,并且在失败时你只需启动新的线程,它会休眠10秒并重新运行回调。

答案 1 :(得分:0)

最后,我找到了为此目的编写的库async-retry。它允许以非常可定制的方式异步重试执行。在内部,当必须使用Java 7时,它会利用ScheduledExecutorService和CompletableFuture(或来自Guava的ListenableScheduledFuture

样本用法(来自项目网页):

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
RetryExecutor executor = new AsyncRetryExecutor(scheduler).
    retryOn(SocketException.class).
    withExponentialBackoff(500, 2).     //500ms times 2 after each retry
    withMaxDelay(10_000).               //10 seconds
    withUniformJitter().                //add between +/- 100 ms randomly
    withMaxRetries(20);

final CompletableFuture<Socket> future = executor.getWithRetry(() ->
        new Socket("localhost", 8080)
);

future.thenAccept(socket ->
        System.out.println("Connected! " + socket)
);

答案 2 :(得分:0)

您也可以查看Failsafe。没有外部依赖,支持Java 1.6 +,死简单API,支持事件监听器,异步API集成等:

RetryPolicy retryPolicy = new RetryPolicy()
  .retryOn(SocketException.class);
  .withMaxRetries(20);

Socket socket = Failsafe.with(retryPolicy).get(() -> new Socket("localhost", 8080));