springmvc处理post请求流程(springmvc使用异步处理请求)
springmvc处理post请求流程(springmvc使用异步处理请求)
同步请求图示: 同步处理的图示如上:HTTP请求,tomcat或其他中间件会有一个相应的线程来处理这个Http请求,所有的业务逻辑都会在这个线程里去执行,最后返回Http响应。但是tomcat等中间件,它们可以管理的线程数是有限的,当数量达到一定程度之后,再有请求进入,会被阻塞掉。 简单异步图示: 异步处理过程:当一个http请求进入后,tomcat等中间件的主线程调用副线程来执行业务逻辑,当副线程处理完成后,主线程再返回结果,在副线程处理整个业务逻辑的中,主线程会空闲出来去出来其他请求,也就是说采用上述这种模式处理http请求,服务器的吞吐量会有有明显的提升。使用异步返回,需使在web.xml将version配置为3.0版本的。 在servlet及所有的filter中配置异步支持。 简单实现如下: 更为复杂的业务场景的异步返回如下所示: Htpp请求通过线程一处理,并将消息发送到消息队列,应用2处于不同的服务器,其接收到消息并将消息返回,线程2监听到处理结果,将消息返回,线程一及线程二不知道对方的存在。这种业务情况,单开一个线程是无法解决的,需要使用DeferredResult类。 简单的实现代码如下: controller层: @Controller @Requestmapping("/test/") @Slf4j public class TestController { @Autowired private MockQueue mockQueue; @Autowired private DeferredResultHolder deferredResultHolder; @RequestMapping("order") @ResponseBody public DeferredResult test() throws InterruptedException { log.info("主线程开始"); String orderNo = RandomUtils.nextInt() ""; mockQueue.setPlaceOrder(orderNo); DeferredResult result = new DeferredResult(); deferredResultHolder.getMap().put(orderNo result); log.info("主线程结束"); return result; } } 伪消息队列类: @Slf4j @Component public class MockQueue { private String placeOrder; private String compeleteOrder; public String getPlaceOrder() { return placeOrder; } public void setPlaceOrder(String placeOrder) throws InterruptedException { new Thread(()->{ log.info("收到下单的请求"); this.placeOrder = placeOrder; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } this.compeleteOrder = placeOrder; log.info("完成下单的请求");}).start(); } public String getCompeleteOrder() { return compeleteOrder; } public void setCompeleteOrder(String compeleteOrder) { this.compeleteOrder = compeleteOrder; } } 伪队列监听类: @Slf4j @Component public class QueueListener implements ApplicationListener{ @Autowired private MockQueue mockQueue; @Autowired private DeferredResultHolder deferredResultHolder; @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { new Thread(() ->{ while (true){ if(StringUtils.isNotBlank(mockQueue.getCompeleteOrder())){ String orderNum = mockQueue.getCompeleteOrder(); log.info("返回订单处理结果" orderNum); deferredResultHolder.getMap().get(orderNum).setResult("success"); mockQueue.setCompeleteOrder(null); }else { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } } 容器类: @Component public class DeferredResultHolder { private Map> map = new HashMap>(); public Map> getMap() { return map; } public void setMap(Map> map) { this.map = map; } }