servlet3的非同步特性

2021-09-02 09:38:32 字數 2199 閱讀 3164

servlet3 比 servlet2.4最大的進步應該是非同步支援了,不再像過去那樣,對於每個請求,只有乙個執行緒在處理,必須等待這個執行緒阻塞處理完畢後,才能給 client 返回響應。

使用非同步處理,新開一條執行緒處理耗時的 task,這樣執行緒不會一直堵塞,可以接著處理其他的client請求。

此處有一誤區,需要澄清的是,servlet3的非同步處理,不是指http的非同步,而是指伺服器端的非同步處理http請求,由以往的乙個執行緒阻塞處理,變成了接到請求後,把費時的io或與db打交道的工作,交給新的執行緒處理,而servlet的執行緒不會一直阻塞在這裡。而http客戶端,仍是同步的等待伺服器端的處理結果。 servlet容器(比如tomcat)一般會分配乙個執行緒來處理乙個來自客戶端的http請求,在這個執行緒傳送回http響應之前,這個執行緒只能屬於這個http請求,而不能離開這個請求,去處理其他請求。

採用servlet3.0之後,當前的執行緒可以開啟非同步處理,開啟非同步處理的時候會得到乙個非同步處理上下文物件,之後當前的執行緒就可以不生成http響應而直接退出去處理其它的http請求,其它執行緒可以在之後通過非同步處理上下文來生成和傳送那個http響應。可見所謂的非同步http其實只是一種可以讓當前的處理執行緒在不生成響應前就離開,而在之後再處理這個http請求的機制。

使用非同步

servlet

主要原因就是因為,在

service

方法中業務邏輯如果碰到

io操作時間比較長的操作,這樣這個

service

方法就會長時間占用

tomcat

容器執行緒池中的執行緒,這樣是不利於其他請求的處理的,當執行緒池中的執行緒處理任務時,任務由於長時間

io操作,肯定會阻塞執行緒處理其他任務,引入非同步

servlet

的目的就是將容器執行緒池和業務執行緒池分離開。在處理大

io的業務操作的時候,把這個操作移動到業務執行緒池中進行,釋放容器執行緒,使得容器執行緒處理其他任務,在業務邏輯執行完畢之後,然後在通知

tomcat

容器執行緒池來繼續後面的操作,這個操作應該是把處理結果

commit

到客戶端或者是

dispatch

到其他servlet上。

從客戶端看來,不論是哪種方式,瀏覽器都在傳送完http請求之後,都必須同步的等待伺服器端的響應。假如瀏覽器傳送完http請求之後,可以在得到伺服器處理結果之前轉而處理其它事情,而在未來的某個時刻,當伺服器處理完請求後,不需要客戶端再傳送請求,就可以發響應發回給瀏覽器,也許那才是真的非同步http了。但是這是違反http的有請求才響應,無請求不響應的基本原則的。 http長連線可以讓客戶端和伺服器在同乙個tcp連線中做多次請求響應,但是並不能改變客戶端和伺服器之間的同步請求響應模式。

儘管servlet3.0的非同步功能不能改變http的協議,在本質上讓瀏覽器和伺服器之間非同步的互動,但是這一功能還是有非常大的意義的。假設接受請求和傳送響應的時間分別為 req和 resp,每個請求都要執行乙個耗時p的操作o,並且o操作會讓呼叫者阻塞,當在p時間內有n個請求傳送過來時,用傳統的處理方式,由於p時間內每個執行緒都不能處理完,servlet容器要分配f(n) = n個執行緒處理請求,如下圖所示:

而用servlet3.0的非同步處理時,處理執行緒可以開啟單一執行緒去做那個耗時p的操作,而把當前請求的非同步處理上下文放入乙個等待佇列中,自己則接著處理其它的請求,假設這個開啟非同步,加入非同步處理上下文的操作需要時間a,那麼需要開啟f(n) = n*(a+req+resp)/(p + req + resp) + 1個執行緒就可以在p時間內處理完所有請求。如下圖所示:

假如執行操作o可以不阻塞,耗時c就返回, 那麼n客戶端每獲得一次資源,需要傳送f(n) = n*p / (req + c + resp) 次請求,而用非同步處理的時候,只需要n次請求。可見當a足夠小於p時,o阻塞訪問時,非同步可以用更少的執行緒處理更多的請求;o非阻塞訪問時,非同步可以減少請求次數。

以web qq為例來看看。使用者傳送訊息時,假設伺服器分發訊息耗時p遠遠大於開啟非同步和把訊息放到待分發佇列的耗時a,那麼採用非同步處理傳送訊息,可以用更少的執行緒處理更多的傳送訊息請求。使用者接受訊息,假設平均p時間內使用者才有新訊息到達,而檢查一次新訊息的耗時遠小於p,那麼採用非同步則可以減少很多客戶端請求。

servlet3的非同步特性

servlet3 比 servlet2.4最大的進步應該是非同步支援了,不再像過去那樣,對於每個請求,只有乙個執行緒在處理,必須等待這個執行緒阻塞處理完畢後,才能給 client 返回響應。使用非同步處理,新開一條執行緒處理耗時的 task,這樣執行緒不會一直堵塞,可以接著處理其他的client請求...

Servlet 3 0中的非同步處理

在以前的servlet規範化,如果servlet作為控制器呼叫了乙個耗時的業務方法,那麼必須等到業務方法完全返回之後才能生成響應,這將使用servlet對業務方法的呼叫變成一種阻塞式的呼叫,因此效率比較低。servlet3.0規範引入了非同步處理來解決這個問題,非同步處理允許servlet重新發起一...

servlet的相關知識3

servlet的重定向原理 客戶傳送乙個請求到伺服器,伺服器匹配servlet,servlet處理完之後呼叫了sendredirect 方法,這個方法是response的方法,所以當servlet處理完之後,看到response.sendredirect 方法,立即向客戶端返回這個響應,響應行告訴客...