【问题标题】:Java - Rest API scenarioJava - Rest API 场景
【发布时间】:2021-09-13 16:49:34
【问题描述】:

我有一个 Rest Controller 方法(它可以是 GET 或 POST 或任何东西),处理过程至少需要 20 分钟或更长时间才能执行。消费者最多只能等待 10 秒。我们应该如何妥善处理这种情况?有设计模式还是什么?我正在征求建议。这是在采访中被问到的。

    @Controller
    public class TestController {
        @RequestMapping("/")
        public @ResponseBody String someMethod() {
            // Logic containing big calculation taking 20 minutes
            return "Some response";
        }
    }

【问题讨论】:

    标签: java api rest time


    【解决方案1】:

    如果客户端调用的进程需要很长时间才能实时响应,请使该进程异步。

    在控制器中,编写一个命令,其中包含有关如何处理消息队列或 kafka 主题的信息。然后放一个听众来听那个话题并做任务。

    同样来自控制器,向客户端返回一个响应,告诉他稍后可以咨询他的操作结果。给他一个链接或 ID 以执行此操作。

    【讨论】:

      【解决方案2】:

      对于简短的回答,您必须使用一种称为长轮询的技术。

      长答案请继续阅读。

      您的问题的答案可能更主观,因为我们必须了解场景。客户在做什么?他想在同一个 HTTP 请求中得到结果吗?或者他对结果不感兴趣,或者他可以通过邮件或其他渠道查看结果?

      假设您的客户在 20 分钟后对结果感兴趣。在这种情况下,您必须在系统中实现长轮询。在春季,我们有一个名为 DeferredResult 的类,它可以帮助您实现结果。

      @RestController
      @RequestMapping("/api")
      public class BakeryController { 
          @GetMapping("/bake/{bakedGood}")
          public DeferredResult<String> publisher(@PathVariable String bakedGood, @RequestParam Integer bakeTime) {
              DeferredResult<String> output = new DeferredResult<>();
              try {
                  Thread.sleep(bakeTime);
                  output.setResult(format("Bake for %s complete and order dispatched. Enjoy!", bakedGood));
              } catch (Exception e) {
                  // ...
              }
              return output;
          }
      }
       
      

      参考:-https://www.baeldung.com/spring-mvc-long-polling

      现在假设您的客户对结果不感兴趣。他只是想执行一些 API,这个服务将完成它本来打算做的工作,并将结果发布到某个地方。在这种情况下,您可以通过 Active MQ 或 Kafka 使用异步处理,您的消费者将在其中处理结果,并将结果存储到所需的通道。通过这种方式实现,您可以立即返回释放线程的请求。

      在 Active MQ 的帮助下使用此方法的示例,JMS 模板如下:-

          @RestController
          public class TestController {
              @RequestMapping("/")
              public ResponseEntity String someMethod(String requestPayload) {
                  // This will be async. It will put the message in the queue and 
                  // will return the response. 
                  jmsTemplate.send("your_queue_name", requestPayload);
                  ResponseEntity.status(HttpStatus.OK).build();
              }
          }
      

      【讨论】:

        【解决方案3】:

        202 Accepted

        与此响应一起发送的表示应该描述请求的当前状态,并指向(或嵌入)一个状态监视器,该监视器可以为用户提供对何时完成请求的估计。

        换句话说,在您确定请求正确且获得授权,并且您有能力处理请求后,向客户发送一份包含估计工作时间的文件(如果有的话)将准备就绪,以及指向可用于检查待处理结果状态的页面的链接。

        这可能意味着获取/生成此请求的唯一标识符,稍后可用于查看事情进展情况。

        【讨论】:

          猜你喜欢
          • 2015-04-30
          • 2018-04-07
          • 2021-12-09
          • 2017-05-03
          • 2022-12-24
          • 1970-01-01
          • 2014-08-03
          • 2015-04-12
          相关资源
          最近更新 更多