有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

首先,我想到了ExecutorRunnable/Future以及ScheduledExecutorService.scheduleWithFixedDelay,但对我来说,它的水平要低得多。第二个想法是演员与AkkaScheduler(为了重新安排时间),但我相信还有其他一些方法

问题。您将使用什么技术进行反应性事件处理,并能够在发生故障时重新安排它们


共 (3) 个答案

  1. # 1 楼答案

    “事件”是一个相当模糊的术语,但我遇到的大多数定义都是关于控制反转的技术之一。这段代码的特点是,您不关心何时以及由谁调用某段代码,而是在什么条件下调用。这意味着您将反转(或者更准确地说是“失去”)对执行流的控制

    现在,您需要事件驱动的处理(因此您不希望处理时间和由谁处理),但您希望指定失败时的定时(严格连接到时间)行为。这对我来说有点自相矛盾

    我想说,如果您使用回调进行反应式编程,并且在失败时,您只需启动新线程,该线程将休眠10秒,然后重新运行回调,您会做得更好

  2. # 2 楼答案

    您也可以签出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));
    
  3. # 3 楼答案

    最后我找到了图书馆async-retry,它就是为了这个目的而写的。它允许以非常可定制的方式异步重试执行。在内部,它利用ScheduledExecutorService和CompletableFuture(或者在必须使用Java7时利用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)
    );