模塊四容器3講27丨新特性tomcat如何支持servlet_第1頁
模塊四容器3講27丨新特性tomcat如何支持servlet_第2頁
模塊四容器3講27丨新特性tomcat如何支持servlet_第3頁
模塊四容器3講27丨新特性tomcat如何支持servlet_第4頁
模塊四容器3講27丨新特性tomcat如何支持servlet_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

Web用將請求處理完,這樣Tomcat程可以立即被回收到線程池,用來響應其他請今天我們就來 下如何開發(fā)一個異步Servlet,以及異步Servlet的工作原理,也就Tomcat是如何支持異步Servlet的,讓你徹底理解它的來龍去脈Servlet我們先通過一個簡單的示例來了解一下異步Servlet的實現(xiàn)代1@WebServlet(urlPatterns={"/async"},asyncSupported=2publicclassAsyncServletextendsHttpServlet34//Web應用線程池,用來處理異步5ExecutorServiceexecutor=67publicvoidservice(HttpServletRequestreq,HttpServletResponse{8//1.調用startAsync或者異步上下9finalAsyncContextctx=//用線程池來執(zhí)行executor.execute(newRunnable()publicvoidrun()//在這里做耗時的操tryctx.getResponse().getWriter().println("Handling}catch(IOExceptione)//3.異步Servlet處理完了調用異步上下文的complete}}}上面的代碼有三個要點通過注解的方式來Servlet,除了@WebServlet注解,還需要加asyncSupported=true的屬性,表明當前的Servlet是一個異步ServletWeb用程序需要調用Request象的startAsync法來拿到一個異步上下AsyncContext。這個上下文保存了請求和響應對象Web應用需要開啟一個新線程來處理耗時的操作,處理完成后需要調用的complete方法。目的是告訴Tomcat,請求已經處理完成這里請你注意,雖然異步Servlet允許用更長的時間來處理請求,但是也有超時限制的,默認是30秒,如果30秒內請求還沒處理完,Tomcat會觸發(fā)超時機制,向瀏覽器返回超時錯誤,如果這個時候你的Web應用再調用 IllegalStateException異常。Servlet通過上面的例子,相信你對Servlet的異步實現(xiàn)有了基本的理解。要理解Tomcat在這個 startAsync方法startAsync方法其實就是創(chuàng)建了一個異步上下文AsyncContext對象,AsyncContext對象的作用是保存請求的中間信息,比如Request和Response對象等上下文信息。你來思這是因為Tomcat的工作線程在Request.startAsync調用之后,就直接結束回到線程池中了,線程本身不會保存任何信息。也就是說一個請求到服務端,執(zhí)行到一半,你的Web應用正在處理,這個時候Tomcat的工作線程沒了,這就需要有個緩存能夠保存原始的Request和Response對象,而這個緩存就是AsyncContext。有了AsyncContext,你的Web應用通過它拿到request和response對象,拿到Request對象后就可以請求信息,請求處理完了還需要通過Response對象將HTTP除了創(chuàng)建AsyncContext對象,startAsync還需要完成一個關鍵任務,那就是告訴Tomcat當前的Servlet處理方法返回時,響應發(fā)到瀏覽器,因為這個時候,響應沒生成呢;并且不能把Request對象和Response對象銷毀,因為后面Web應用還要用在Tomcat中,負責flush響應數(shù)據的是CoyoteAdaptor,它還會銷毀Request對象和Response對象,因此需要通過某種機制通知CoyoteAdaptor,具體來說是通過下面這行代1this.request.getCoyoteRequest().action(ActionCode.ASYNC_START,你可以把它理解為一個Callback,在這個action法里設置了Request象的狀態(tài),設置它為一個異步Servlet請求。我們知道連接器是調用CoyoteAdapter的service方法來處理請求的,而CoyoteAdapter會調用容器的service方法,當容器的service方法返回時,CoyoteAdapter斷當前的請求是不是異步Servlet求,如果是,就不會銷毀Request和Response對象,也不會把響應信息發(fā)到瀏覽器。你可以通過下面的代碼理解一下,這是CoyoteAdapter的service方法,我對它進行了簡化:代1publicvoidservice(org.apache.coyote.Requestreq,org.apache.coyote.Responseres)2//調用容器的service方法處理請getFirst().invoke(request,6//如果是異步Servlet請求,僅僅設//否則說明是同步Servlet請求,就將響應數(shù)據刷到瀏覽if(request.isAsync())async=}else //如果不是異步Servlet請求,就銷毀Request對象和Responseif(!async) 21接下來,當CoyoteAdaptor的service方法返回到ProtocolHandler組件時,ProtocolHandler判斷返回值,如果當前請求是一個異步Servlet請求,它會把當前Socket協(xié)議處理者Processor存起來,將SocketWrapper象和相應的Processor存到一個Map數(shù)據結構里。代1privatefinalMap<S,Processor>connections=new之所以要緩存是因為這個請求接下來還要接著處理,還是由原來的Processor過SocketWrapper就能從Map里找到相應的Pplete方法 plete方法,當請求處理完成時,Web應用調用這個方這件事情不能由Web應用線程來做,也就是說 發(fā)送到瀏覽器,因為這件事情應該由Tomcat線程來做,但具體怎么做呢?我們知道,連接器中的Endpoint組件檢測到有請求數(shù)據達到時,會創(chuàng)建一cessor象交給線程池去處理,因此Endpoint通信處理和具體請求處理在在異步Servlet的場景里,Web應用通過調用 cessor任務類,交給線程池處理。對于異步Servlet請求來說,相應的Socket和協(xié)議處理組件Processor都被緩存起來了,并且這些對象都可以通過Request講到這里,你可能已經猜 plete是如何實現(xiàn)的了代publicvoidcomplete()//檢查狀態(tài),我們先忽略這4//調用Request對象的action方法,其實就是通知連接器,這個異步請求處理 PLETE,78我們可以看到complete方法調用了Request對象的action方法。而在action方法里,則是調用了Processor的processSocketEvent方法,并且傳入了操作碼OPEN_READ代 PLETE:if plete())processSocketEvent(SocketEvent.OPEN_READ, 7我們接著看processSocketEvent法,它調用SocketWrapperprocessSocket代protectedvoidprocessSocketEvent(SocketEventevent,booleandispatch)SocketWrapperBase<?>socketWrapper=if(socketWrapper!=null)socketWcessSocket(event, 6而SocketWrapper的processSocket方創(chuàng) cessor任務類,并通Tomcat線程池來處理代publicbooleanprocessSocket(SocketWrapperBase<S>SocketEventevent,booleandispatch)3if(socketWrapper==null)return 7 cessorBase<S>sc=if(sc==null)sc=createcessor(socketWrapper,}elsesc.reset(socketWrapper, //線程池運Executorexecutor=if(dispatch&&executor!=null)}else 21請你注意createcessor函數(shù)的第二個參數(shù)是SocketEvent,這里我們傳入的是OPEN_READ。通過這個參數(shù),我們就能控制cessor的行為,因為我們不需要再把請求發(fā)送到容器進行處理,只需要向瀏覽器端發(fā)送數(shù)據,并且重新在這個Socket上監(jiān)最后我通過一張在幫你理解一下整個過非阻塞I/O模型可以利用很少的線程處理大量的連接,提高了并發(fā)度,本質就是通過Selector線程查詢多個Socket的I/O,減少了線程的阻塞等待同樣,異步Servlet機制也是減少了線程的阻塞等待,將Tomcat線程和業(yè)務線程分Tomca線程不再等待業(yè)務代碼的執(zhí)行那什么樣的場景適合異步erlet呢?適合的場景有很多,最主要的還是根據你的實際情況,如果你拿是否適合異步ervlet,就看一條:如果你發(fā)現(xiàn)Tomat的線程不夠了,大量線程阻塞在等待Web應用的處理上,而Web應用又沒有優(yōu)化的空間了,確實需要長時間處理,這個時候你不妨嘗試一下異步Serlet。異步Servlet將Tomcat線程和Web應用線程分開,體現(xiàn)了的思想,也就是把不同的業(yè)務處理所使用的資源開,使得它們互不干擾,尤其是低優(yōu)先級的業(yè)務不能影響高優(yōu)先級的業(yè)務。你可以思考一下,在你的Web應用內部,是不是也可以運用這種設計思想呢?不知道今

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論