DeferredResult的使用

分类:软件编程
阅读:488
作者:majingjing
发布:2021-11-22 08:50

DeferredResult的使用

功能

当一个请求到达API接口,在没有超时或者DeferredResult对象设置setResult时,接口不会返回,但是Servlet容器线程会结束,DeferredResult另起线程来进行结果处理(即这种操作提升了\服务短时间的吞吐能力**),并setResult,如此以来这个请求不会占用服务连接池太久,如果超时或设置setResult,接口会立即返回。

使用DeferredResult的流程:

  • 浏览器发起异步请求
  • 请求到达服务端被挂起
  • 向浏览器进行响应,分为两种情况:
    • 调用DeferredResult.setResult(),请求被唤醒,返回结果
    • 超时,返回一个你设定的结果
  • 浏览器得到响应

示例代码

  1. @RestController
  2. @Validated
  3. @Slf4j
  4. public class AsyncController {
  5. static final Map<String,DeferredResult<String>> MAP = new HashMap<>(16);
  6. @GetMapping("/call")
  7. public DeferredResult<String> process(String name,Long t){
  8. DeferredResult<String> deferredResult = new DeferredResult<String>(t,"time out");
  9. MAP.put(name,deferredResult);
  10. deferredResult.onCompletion(()->{
  11. log.info("onCompletion t: "+ t);
  12. });
  13. deferredResult.onTimeout(()->{
  14. log.info("onTimeout t: "+ t);
  15. });
  16. log.info("process t: "+ t);
  17. return deferredResult;
  18. }
  19. @GetMapping("/call/over")
  20. public String logs(String name){
  21. DeferredResult<String> deferredResult = MAP.remove(name);
  22. deferredResult.setResult("call/over -> success");
  23. return "success";
  24. }
  25. }

测试

结果为 : time out

控制台输出:

  1. process t: 20000
  2. onTimeout t: 20000
  3. onCompletion t: 20000

结果为: call/over -> success

控制台输出:

  1. process t: 20000
  2. onCompletion t: 20000