成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Servlet 3.0 異步處理詳解

kid143 / 1454人閱讀

摘要:但是這樣依然有一個問題,考慮以下場景有一個容器,線程池大小。這個時候工程師發(fā)現(xiàn)了問題,擴(kuò)展了線程池大小到,但是負(fù)載依然持續(xù)走高,現(xiàn)在有個到,依然無法響應(yīng)。你可以修改的線程池大小,把它和比較結(jié)果來驗(yàn)證這一結(jié)論。

Github地址

相關(guān)系列文章:

Servlet 3.1 Async IO分析

Spring MVC異步處理的幾種方式

Servlet 3.0 開始提供了AsyncContext用來支持異步處理請求,那么異步處理請求到底能夠帶來哪些好處?

Web容器一般來說處理請求的方式是:為每個request分配一個thread。我們都知道thread的創(chuàng)建不是沒有代價的,Web容器的thread pool都是有上限的。
那么一個很容易預(yù)見的問題就是,在高負(fù)載情況下,thread pool都被占著了,那么后續(xù)的request就只能等待,如果運(yùn)氣不好客戶端會報(bào)等待超時的錯誤。
在AsyncContext出現(xiàn)之前,解決這個問題的唯一辦法就是擴(kuò)充Web容器的thread pool。

但是這樣依然有一個問題,考慮以下場景:

有一個web容器,線程池大小200。有一個web app,它有兩個servlet,Servlet-A處理單個請求的時間是10s,Servlet-B處理單個請求的時間是1s。
現(xiàn)在遇到了高負(fù)載,有超過200個request到Servlet-A,如果這個時候請求Servlet-B就會等待,因?yàn)樗蠬TTP thread都已經(jīng)被Servlet-A占用了。
這個時候工程師發(fā)現(xiàn)了問題,擴(kuò)展了線程池大小到400,但是負(fù)載依然持續(xù)走高,現(xiàn)在有400個request到Servlet-A,Servlet-B依然無法響應(yīng)。

看到問題了沒有,因?yàn)?strong>HTTP thread和Worker thread耦合在了一起(就是同一個thread),所以導(dǎo)致了當(dāng)大量request到一個耗時操作時,就會將HTTP thread占滿,導(dǎo)致整個Web容器就會無法響應(yīng)。

但是如果使用AsyncContext,我們就可以將耗時的操作交給另一個thread去做,這樣HTTP thread就被釋放出來了,可以去處理其他請求了。

注意,只有使用AsyncContext才能夠達(dá)到上面所講的效果,如果直接new Thread()或者類似的方式的,HTTP thread并不會歸還到容器。

下面是一個官方的例子:

@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true)
public class AsyncServlet extends HttpServlet {
   /* ... Same variables and init method as in SyncServlet ... */

   @Override
   public void doGet(HttpServletRequest request, 
                     HttpServletResponse response) {
      response.setContentType("text/html;charset=UTF-8");
      final AsyncContext acontext = request.startAsync();
      acontext.start(new Runnable() {
         public void run() {
            String param = acontext.getRequest().getParameter("param");
            String result = resource.process(param);
            HttpServletResponse response = acontext.getResponse();
            /* ... print to the response ... */
            acontext.complete();
            }
      });
   }
}
陷阱

在這個官方例子里,每個HTTP thread都會開啟另一個Worker thread來處理請求,然后把HTTP thread就歸還給Web容器。但是看AsyncContext.start()方法的javadoc:

Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable.

實(shí)際上這里并沒有規(guī)定Worker thread到底從哪里來,也許是HTTP thread pool之外的另一個thread pool?還是說就是HTTP thread pool?

The Limited Usefulness of AsyncContext.start()文章里寫道:不同的Web容器對此有不同的實(shí)現(xiàn),不過Tomcat實(shí)際上是利用HTTP thread pool來處理AsyncContext.start()的。

這也就是說,我們原本是想釋放HTTP thread的,但實(shí)際上并沒有,因?yàn)橛蠬TTP thread依然被用作Worker thread,只不過這個thread和接收請求的HTTP thread不是同一個而已。

這個結(jié)論我們也可以通過AsyncServlet1和SyncServlet的Jmeter benchmark看出來,兩者的throughput結(jié)果差不多。啟動方法:啟動Main,然后利用Jmeter啟動benchmark.jmx(Tomcat默認(rèn)配置下HTTP thread pool=200)。

使用ExecutorService

前面看到了Tomcat并沒有多帶帶維護(hù)Worker thread pool,那么我們就得自己想辦法搞一個,見AsyncServlet2,它使用了一個帶Thread pool的ExecutorService來處理AsyncContext。

其他方式

所以對于AsyncContext的使用并沒有固定的方式,你可以根據(jù)實(shí)際需要去采用不同的方式來處理,為此你需要一點(diǎn)Java concurrent programming的知識。

對于性能的誤解

AsyncContext的目的并不是為了提高性能,也并不直接提供性能提升,它提供了把HTTP thread和Worker thread解藕的機(jī)制,從而提高Web容器的響應(yīng)能力

不過AsyncContext在某些時候的確能夠提高性能,但這個取決于你的代碼是怎么寫的。
比如:Web容器的HTTP thread pool數(shù)量200,某個Servlet使用一個300的Worker thread pool來處理AsyncContext。
相比Sync方式Worker thread pool=HTTP thread pool=200,在這種情況下我們有了300的Worker thread pool,所以肯定能夠帶來一些性能上的提升(畢竟干活的人多了)。

相反,如果當(dāng)Worker thread的數(shù)量<=HTTP thread數(shù)量的時候,那么就不會得到性能提升,因?yàn)榇藭r處理請求的瓶頸在Worker thread。
你可以修改AsyncServlet2的線程池大小,把它和SyncServlet比較benchmark結(jié)果來驗(yàn)證這一結(jié)論。

一定不要認(rèn)為Worker thread pool必須比HTTP thread pool大,理由如下:

兩者職責(zé)不同,一個是Web容器用來接收外來請求,一個是處理業(yè)務(wù)邏輯

thread的創(chuàng)建是有代價的,如果HTTP thread pool已經(jīng)很大了再搞一個更大的Worker thread pool反而會造成過多的Context switch和內(nèi)存開銷

AsyncContext的目的是將HTTP thread釋放出來,避免被操作長期占用進(jìn)而導(dǎo)致Web容器無法響應(yīng)

所以在更多時候,Worker thread pool不會很大,而且會根據(jù)不同業(yè)務(wù)構(gòu)建不同的Worker thread pool。
比如:Web容器thread pool大小200,一個慢速Servlet的Worker thread pool大小10,這樣一來,無論有多少請求到慢速操作,它都不會將HTTP thread占滿導(dǎo)致其他請求無法處理。

相關(guān)資料

Java EE 7 Tutorial: Java Servlet Technology - Asynchronous Processing

The Limited Usefulness of AsyncContext.start()

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70726.html

相關(guān)文章

  • Servlet 3.1 Async IO分析

    摘要:于是提供了機(jī)制,使得從中讀往里寫變成異步動作。這是因?yàn)榭蛻舳说臄?shù)據(jù)推送速度太慢了,容器先將收回,當(dāng)容器發(fā)現(xiàn)可以讀取到新數(shù)據(jù)的時候,再分配一個去讀,如此循環(huán)直到全部讀完為止。注意和不能同時使用。 Github地址 相關(guān)系列文章: Servlet 3.0 異步處理詳解 Spring MVC異步處理的幾種方式 Servlet Async Processing提供了一種異步請求處理的手段(...

    n7then 評論0 收藏0
  • Spring MVC異步處理簡介

    摘要:異步處理簡介地址相關(guān)系列文章異步處理詳解分析本文講到的所有特性皆是基于的,不是基于的。用于異步返回結(jié)果,使用自己的,使用負(fù)責(zé)處理它。配置執(zhí)行異步操作需要用到,這個可以在用方法來提供相關(guān)文檔。 Spring MVC異步處理簡介 Github地址 相關(guān)系列文章: Servlet 3.0 異步處理詳解 Servlet 3.1 Async IO分析 本文講到的所有特性皆是基于Servlet...

    Sike 評論0 收藏0
  • 4.1、異步請求處理(TODO)

    摘要:本部分示例見這個項(xiàng)目的分支下的中引進(jìn)了基于異步請求處理的。同時主容器線程退出釋放并允許處理其他請求。對的調(diào)用返回,可以被用于異步處理之上的進(jìn)一步控制。 ??本部分示例見這個項(xiàng)目的 mvc 分支下的 AsyncController.java ??Spring MVC 3.2 中引進(jìn)了基于異步請求處理的 Servlet 3。除了返回一個值,一個控制器方法現(xiàn)在可以返回一個java.util...

    AbnerMing 評論0 收藏0
  • 關(guān)于web.xml配置的那些事兒

    摘要:的版本增加了對事件監(jiān)聽程序的支持,事件監(jiān)聽程序在建立修改和刪除會話或環(huán)境時得到通知。元素指出事件監(jiān)聽程序類。過濾器配置將一個名字與一個實(shí)現(xiàn)接口的類相關(guān)聯(lián)。 1.簡介 web.xml文件是Java web項(xiàng)目中的一個配置文件,主要用于配置歡迎頁、Filter、Listener、Servlet等,但并不是必須的,一個java web項(xiàng)目沒有web.xml文件照樣能跑起來。Tomcat容器/...

    zhichangterry 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<