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; } }


※詳解MBR分區結構以及GPT分區結構
※如何在Windows系統中設置Python程序定時運行
TAG:程序員小新人學習 |