Tomcat怎么實(shí)現(xiàn)異步Servlet
有時Servlet在生成響應(yīng)報文前必須等待某些耗時的操作,比如在等待一個可用的JDBC連接或等待一個遠(yuǎn)程Web服務(wù)的響應(yīng)。對于這種情況servlet規(guī)范中定義了異步處理方式,由于Servlet中等待阻塞會導(dǎo)致Web容器整體的處理能力低下,所以對于比較耗時的操作可以放置到另外一個線程中進(jìn)行處理,此過程保留連接的請求和響應(yīng)對象,在處理完成之后可以把處理的結(jié)果通知到客戶端。
下面先看Servlet在同步情況下的處理過程,如圖所示,Tomcat的客戶端請求由管道處理最后會通過Wrapper容器的管道,這時它會調(diào)Servlet實(shí)例的service方法進(jìn)行邏輯處理,處理完后響應(yīng)客戶端,整個處理由Tomcat的Executor線程池的線程處理,而線程池的最大線程數(shù)使有限制的,所以這個處理過程越短、越快把線程讓回線程池就越好。但如果Servlet中的處理邏輯耗時越長就會導(dǎo)致長期地占用Tomcat的處理線程池,影響Tomcat的整體處理能力。

為了解決上面的問題引入了支持異步的Servlet,同樣是客戶端請求到來,然后通過管道最后進(jìn)入到Wrapper容器的管道,調(diào)用Servlet實(shí)例的service后,創(chuàng)建一個異步上下文將耗時的邏輯操作封裝起來,交給用戶自己定義的線程池,這時Tomcat的處理線程就能馬上回到Executor線程池,而不用等待耗時的操作完成才讓出線程,從而提升了Tomcat的整體處理能力。這里要注意的是,由于后面做完耗時的操作后還需要對客戶端響應(yīng),所以需要保持住Request和Response對象,以便輸出響應(yīng)報文到客戶端。

再結(jié)合一個簡單的異步代碼來看Tomcat對Servlet異步的實(shí)現(xiàn):
public class AsyncServlet extends HttpServlet {
ScheduledThreadPoolExecutor userExecutor = new ScheduledThreadPoolExecutor(5);
public void doGet(HttpServletRequest req, HttpServletResponse res) {
AsyncContext aCtx = req.startAsync(req, res);
userExecutor.execute(new AsyncHandler(aCtx));
}
}
public class AsyncHandler implements Runnable {
private AsyncContext ctx;
public AsyncHandler(AsyncContext ctx) {
this.ctx = ctx;
}
@Override
public void run() {
//耗時操作
PrintWriter pw;
try {
pw = ctx.getResponse().getWriter();
pw.print("done!");
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
ctx.complete();
}
}
我們創(chuàng)建一個AsyncServlet,它定義了一個userExecutor線程池專門用于處理該Servlet的所有請求的耗時的邏輯操作。這樣就不會占用Tomcat內(nèi)部的Executor線程池,影響到對其他Servlet的處理。這種思想有點(diǎn)像資源隔離,耗時的操作統(tǒng)一由指定的線程池處理,而不要影響其它耗時少的請求處理。
Servlet的異步的實(shí)現(xiàn)就很好理解了,startAsync方法其實(shí)就是創(chuàng)建了一個異步上下文AsyncContext對象,該對象封裝了請求和響應(yīng)對象。然后創(chuàng)建一個任務(wù)用于處理耗時邏輯,后面通過AsyncContext對象獲得響應(yīng)對象并對客戶端響應(yīng),輸出“done!”。完成后要通過complete方法告訴Tomcat內(nèi)部我已經(jīng)處理完,Tomcat就會請求對象和響應(yīng)對象進(jìn)行回收處理或關(guān)閉連接。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用IDEA創(chuàng)建servlet?JavaWeb?應(yīng)用及使用Tomcat本地部署的實(shí)現(xiàn)
- IDEA2021 tomcat10 servlet 較新版本踩坑問題
- 深入了解tomcat中servlet的創(chuàng)建方式實(shí)現(xiàn)
- tomcat關(guān)于配置servlet的url-pattern的問題思路詳解
- 詳解Tomcat是如何實(shí)現(xiàn)異步Servlet的
- 詳解如何通過tomcat的ManagerServlet遠(yuǎn)程部署項(xiàng)目
- tomcat中Servlet的工作機(jī)制詳細(xì)介紹
- Tomcat架構(gòu)設(shè)計(jì)及Servlet作用規(guī)范講解
相關(guān)文章
在Tomcat中部署Web項(xiàng)目的操作方法(必看篇)
下面小編就為大家?guī)硪黄赥omcat中部署Web項(xiàng)目的操作方法(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
詳解tomcat設(shè)置默認(rèn)路徑致使項(xiàng)目url沖突解決方法
這篇文章主要介紹了詳解tomcat設(shè)置默認(rèn)路徑致使項(xiàng)目url沖突解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
Tomcat在linux環(huán)境中開機(jī)自啟(定時重啟)的方法
我們經(jīng)常會遇到服務(wù)器斷電或異常,而異常后tomcat中部署的web項(xiàng)目需要我手動去啟動,為此,特別貢獻(xiàn)出Linux環(huán)境中Tomcat開機(jī)自啟的方式供學(xué)習(xí)使用,需要的朋友可以參考下2023-10-10
idea搭建項(xiàng)目找不到Tomcat的解決方法(圖文教程)
今天在公司中導(dǎo)入公司項(xiàng)目,需要配置tomcat,結(jié)果發(fā)現(xiàn)找不到,所以這篇文章主要給大家介紹了關(guān)于idea搭建項(xiàng)目找不到Tomcat的解決方法,需要的朋友可以參考下2023-07-07
詳解Tomcat是如何實(shí)現(xiàn)異步Servlet的
這篇文章主要介紹了詳解Tomcat是如何實(shí)現(xiàn)異步Servlet的,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10

