国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > Tomcat > 正文

詳解Tomcat是如何實現異步Servlet的

2024-09-06 19:00:54
字體:
來源:轉載
供稿:網友

前言

通過我之前的Tomcat系列文章,相信看我博客的同學對Tomcat應該有一個比較清晰的了解了,在前幾篇博客我們討論了Tomcat在SpringBoot框架中是如何啟動的,討論了Tomcat的內部組件是如何設計以及請求是如何流轉的,那么我們這邊博客聊聊Tomcat的異步Servlet,Tomcat是如何實現異步Servlet的以及異步Servlet的使用場景。

手擼一個異步的Servlet

我們直接借助SpringBoot框架來實現一個Servlet,這里只展示Servlet代碼:

@WebServlet(urlPatterns = "/async",asyncSupported = true)@Slf4jpublic class AsyncServlet extends HttpServlet { ExecutorService executorService =Executors.newSingleThreadExecutor(); @Override  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  //開啟異步,獲取異步上下文  final AsyncContext ctx = req.startAsync();  // 提交線程池異步執行  executorService.execute(new Runnable() {   @Override   public void run() {    try {     log.info("async Service 準備執行了");     //模擬耗時任務     Thread.sleep(10000L);     ctx.getResponse().getWriter().print("async servlet");     log.info("async Service 執行了");    } catch (IOException e) {     e.printStackTrace();    } catch (InterruptedException e) {     e.printStackTrace();    }    //最后執行完成后完成回調。    ctx.complete();   }  }); }

上面的代碼實現了一個異步的Servlet,實現了 doGet 方法注意在SpringBoot中使用需要再啟動類加上 @ServletComponentScan 注解來掃描Servlet。既然代碼寫好了,我們來看看實際運行效果。

我們發送一個請求后,看到頁面有響應,同時,看到請求時間花費了10.05s,那么我們這個Servlet算是能正常運行啦。有同學肯定會問,這不是異步servlet嗎?你的響應時間并沒有加快,有什么用呢?對,我們的響應時間并不能加快,還是會取決于我們的業務邏輯,但是我們的異步servlet請求后,依賴于業務的異步執行,我們可以立即返回,也就是說,Tomcat的線程可以立即回收,默認情況下,Tomcat的核心線程是10,最大線程數是200,我們能及時回收線程,也就意味著我們能處理更多的請求,能夠增加我們的吞吐量,這也是異步Servlet的主要作用。

異步Servlet的內部原理

了解完異步Servlet的作用后,我們來看看,Tomcat是如何是先異步Servlet的。其實上面的代碼,主要核心邏輯就兩部分, final AsyncContext ctx = req.startAsync();ctx.complete(); 那我們來看看他們究竟做了什么?

 public AsyncContext startAsync(ServletRequest request,   ServletResponse response) {  if (!isAsyncSupported()) {   IllegalStateException ise =     new IllegalStateException(sm.getString("request.asyncNotSupported"));   log.warn(sm.getString("coyoteRequest.noAsync",     StringUtils.join(getNonAsyncClassNames())), ise);   throw ise;  }  if (asyncContext == null) {   asyncContext = new AsyncContextImpl(this);  }  asyncContext.setStarted(getContext(), request, response,    request==getRequest() && response==getResponse().getResponse());  asyncContext.setTimeout(getConnector().getAsyncTimeout());  return asyncContext; }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 濉溪县| 买车| 延寿县| 潮州市| 台江县| 兖州市| 岐山县| 渭南市| 郁南县| 石棉县| 崇仁县| 建阳市| 威海市| 鹤岗市| 临邑县| 昌平区| 罗平县| 靖宇县| 商洛市| 莱州市| 康马县| 五常市| 盐城市| 岳阳县| 思茅市| 南岸区| 郧西县| 常德市| 昆山市| 昌图县| 滁州市| 五河县| 灵丘县| 莱州市| 临猗县| 师宗县| 皮山县| 丰镇市| 香河县| 托里县| 三都|