如何在关机时等待 RestTemplate 响应? [英] How to wait on RestTemplate responses on shutdown?

查看:52
本文介绍了如何在关机时等待 RestTemplate 响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 springRestTemplatePOST 请求发送到网络服务器.

I'm using spring with RestTemplate to send POST requests to a webserver.

当我的应用程序关闭时(例如从 tomcat 中取消部署),关闭应该延迟到收到所有待处理的响应(在超时内).

When my application is shut down (eg undeployed from tomcat), the shutdown should be delayed until all pending responses are received (within a timeout).

restTemplate 在底层使用 HttpComponentsClientHttpRequestFactory.

The restTemplate uses HttpComponentsClientHttpRequestFactory under the hood.

问题:如何告诉 spring 延迟关闭?@PreDestroy 可能是一种可能性,但如何检测 restTemplate 上的待处理请求?

Question: how can I tell spring to delay the shutdown? @PreDestroy could be one possibility, but how can I detect pending requests on the restTemplate?

推荐答案

你可以用 ExecutorService 执行所有的请求,然后添加一个 @PreDestroy 钩子来等待所有在给定的超时时间内完成的任务.你的服务可以这样

You can execute all the requests with ExecutorService and then add a @PreDestroy hook to wait for all tasks to be completed within a given timeout. Your service can be like this

@Slf4j
@Component
public class SenderService {
  private static final int TWO_SECONDS = 2;
  private RestTemplate restTemplate;
  private ExecutorService executorService;

  public SenderService() {
    this.restTemplate = new RestTemplate();
    this.executorService = Executors.newFixedThreadPool(1);
  }

  public void sendRequest() throws Exception {
    executorService.submit(() -> {
      ZonedDateTime now = ZonedDateTime.now();
      log.info("Sending request at {} ...", now);
      restTemplate.getForObject("https://httpbin.org/delay/{delay}", Void.class, TWO_SECONDS, now);
      log.info("Response received for request at {}", now);
      return null;
    }).get();
  }

  @PreDestroy
  public void destroy() throws InterruptedException {
    log.info("Shutting down sender service...");
    executorService.shutdown();
    executorService.awaitTermination(3, TimeUnit.SECONDS);
    log.info("Sender service terminated.");
  }
}

测试这个的简单方法是运行下面的应用程序并在某个时候终止它.

The simple way to test this is running the application below and terminating it at some point.

@SpringBootApplication
public class Application {

  public static void main(final String[] args) throws Exception {
    ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
    SenderService senderService = run.getBean(SenderService.class);
    while (true) {
      senderService.sendRequest();
    }
  }
}

如果您正常关闭应用程序,您会看到如果请求发送到 delay endpointexecutorService 将等待最多 3 秒待完成的任务然后终止组件.executorService.shutdown() 启动关闭,其中执行先前提交的任务,但不会接受新任务.

If you gracefully shut down the application, you'll see that if a request is sent to delay endpoint, the executorService is going to wait up to 3 seconds for the task to be completed and then terminate the component. executorService.shutdown() initiates a shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

此代码使用带有嵌入式 tomcat 的 spring-boot,但相同的方法可以应用于任何 spring 应用程序上下文.

This code is using spring-boot with embedded tomcat, but the same approach could be applied to any spring application context.

这篇关于如何在关机时等待 RestTemplate 响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆