springmvc使用异步处理请求

同步请求图示:

同步处理的图示如上:HTTP请求,tomcat或其他中间件会有一个相应的线程来处理这个Http请求,所有的业务逻辑都会在这个线程里去执行,最后返回Http响应。但是tomcat等中间件,它们可以管理的线程数是有限的,当数量达到一定程度之后,再有请求进入,会被阻塞掉。

简单异步图示:


异步处理过程:当一个http请求进入后,tomcat等中间件的主线程调用副线程来执行业务逻辑,当副线程处理完成后,主线程再返回结果,在副线程处理整个业务逻辑的中,主线程会空闲出来去出来其他请求,也就是说采用上述这种模式处理http请求,服务器的吞吐量会有有明显的提升。使用异步返回,需使在web.xmlversion配置为3.0版本的。

servlet及所有的filter中配置异步支持。

扫描二维码关注公众号,回复: 1860750 查看本文章

简单实现如下:

更为复杂的业务场景的异步返回如下所示:

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<String> test() throws InterruptedException {
        log.info("主线程开始");
        String orderNo = RandomUtils.nextInt() + "";
        mockQueue.setPlaceOrder(orderNo);
        DeferredResult<String> result = new DeferredResult<String>();
        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<String,DeferredResult<String>> map = new HashMap<String,DeferredResult<String>>();

    public Map<String, DeferredResult<String>> getMap() {
        return map;
    }

    public void setMap(Map<String, DeferredResult<String>> map) {
        this.map = map;
    }
}



猜你喜欢

转载自blog.csdn.net/qq_34871626/article/details/79762744