我想实现一个微服务,它在收到请求后(通过消息队列)将尝试通过对外部服务的REST / SOAP调用来执行它。成功时,回复应该通过MQ发回,但失败请求重新安排以便稍后执行(使用一些自定义算法,如10秒,1分钟,10分钟,超时 - 放弃)。在指定的时间后,应将失败消息发送回请求者。
它应该在Java 8
和/或Groovy
上运行。事件持久性不是必需的。
首先我虽然关于Executor
和Runnable/Future
以及ScheduledExecutorService.scheduleWithFixedDelay
,但它对我来说看起来很低。第二个想法是有Akka
和Scheduler(重新安排)的演员,但我确信可能还有其他方法。
问题即可。您可以使用什么技术进行反应事件处理,并能够在失败时重新安排它们?
答案 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));