最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Servlet3.0異步處理問題

 更新時(shí)間:2017年12月07日 09:23:17   投稿:laozhang  
這篇文章主要介紹了Java中Servlet3.0異步處理的原理以及遇到的問題分析,需要的朋友參考一下。

通過本篇文章主要給大家講解了在JAVA開發(fā)中Servlet3.0異步處理遇到的問題以及處理辦法,以下是具體內(nèi)容:

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

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

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

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

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

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

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

下面是一個(gè)官方的例子:

@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();
   }
  });
 }
}

陷阱

在這個(gè)官方例子里,每個(gè)HTTP thread都會(huì)開啟另一個(gè)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之外的另一個(gè)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,只不過這個(gè)thread和接收請求的HTTP thread不是同一個(gè)而已。

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

使用ExecutorService

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

其他方式

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

對于性能的誤解

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

不過AsyncContext在某些時(shí)候的確能夠提高性能,但這個(gè)取決于你的代碼是怎么寫的。
比如:Web容器的HTTP thread pool數(shù)量200,某個(gè)Servlet使用一個(gè)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ù)量的時(shí)候,那么就不會(huì)得到性能提升,因?yàn)榇藭r(shí)處理請求的瓶頸在Worker thread。
你可以修改AsyncServlet2的線程池大小,把它和SyncServlet比較benchmark結(jié)果來驗(yàn)證這一結(jié)論。

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

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

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

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

所以在更多時(shí)候,Worker thread pool不會(huì)很大,而且會(huì)根據(jù)不同業(yè)務(wù)構(gòu)建不同的Worker thread pool。

比如:Web容器thread pool大小200,一個(gè)慢速Servlet的Worker thread pool大小10,這樣一來,無論有多少請求到慢速操作,它都不會(huì)將HTTP thread占滿導(dǎo)致其他請求無法處理。

相關(guān)文章

  • SpringMVC和Ajax的交互詳解(手工處理)

    SpringMVC和Ajax的交互詳解(手工處理)

    Ajax即異步的?JavaScript和XML,是一種無需重新加載整個(gè)網(wǎng)頁的情況下,能夠更新部分模塊的網(wǎng)頁技術(shù),下面這篇文章主要給大家介紹了關(guān)于SpringMVC和Ajax交互的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Maven2 plugin開發(fā)教程詳解

    Maven2 plugin開發(fā)教程詳解

    這篇文章主要為大家詳細(xì)介紹了Maven2 plugin的開發(fā)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • SpringBoot激活profiles的幾種方式

    SpringBoot激活profiles的幾種方式

    多環(huán)境是最常見的配置隔離方式之一,可以根據(jù)不同的運(yùn)行環(huán)境提供不同的配置信息來應(yīng)對不同的業(yè)務(wù)場景,這篇文章主要介紹了SpringBoot激活profiles的幾種方式,需要的朋友可以參考下
    2019-10-10
  • 解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象

    解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象

    Flink API提供了開發(fā)的接口,此外,為了實(shí)現(xiàn)業(yè)務(wù)邏輯,還必須為開發(fā)者提供自定義業(yè)務(wù)邏輯的能力,下面為大家解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象
    2021-08-08
  • SpringBoot+Vue實(shí)現(xiàn)動(dòng)態(tài)菜單的思路梳理

    SpringBoot+Vue實(shí)現(xiàn)動(dòng)態(tài)菜單的思路梳理

    這篇文章主要為大家詳細(xì)介紹了利用SpringBoot+Vue實(shí)現(xiàn)動(dòng)態(tài)菜單的思路梳理,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下
    2022-07-07
  • java中transient關(guān)鍵字的作用解析

    java中transient關(guān)鍵字的作用解析

    這篇文章主要介紹了java中transient關(guān)鍵字的作用解析,日常業(yè)務(wù)中,為了安全起見,有些敏感信息我們不希望在網(wǎng)絡(luò)間被傳輸可以使用transient對字段進(jìn)行修飾,不進(jìn)行序列化,則返回獲取到的字段為null,需要的朋友可以參考下
    2023-11-11
  • SpringBoot集成WebSocket的兩種方式(JDK內(nèi)置版和Spring封裝版)

    SpringBoot集成WebSocket的兩種方式(JDK內(nèi)置版和Spring封裝版)

    這篇文章主要介紹了SpringBoot集成WebSocket的兩種方式,這兩種方式為JDK內(nèi)置版和Spring封裝版,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Java設(shè)計(jì)模式之中介模式

    Java設(shè)計(jì)模式之中介模式

    這篇文章主要介紹了Java設(shè)計(jì)模式之中介模式,中介模式(Mediator?Pattern),屬于行為型設(shè)計(jì)模式,目的是把系統(tǒng)中對象之間的調(diào)用關(guān)系從一對多轉(zhuǎn)變成一對一的調(diào)用關(guān)系,以此來降低多個(gè)對象和類之間的通信復(fù)雜性,需要的朋友可以參考下
    2023-12-12
  • Java版C語言版簡單使用靜態(tài)語言實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的方法

    Java版C語言版簡單使用靜態(tài)語言實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的方法

    本文給大家分享java版和C語言版簡單使用靜態(tài)語言實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-10-10
  • Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題與讀者寫者問題詳解

    Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題與讀者寫者問題詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題與讀者寫者問題詳解,小編覺得挺不錯(cuò)的,這里分享給大家,供需要的親朋好友參考。
    2017-11-11

最新評(píng)論

定边县| 平武县| 玉林市| 宁强县| 漯河市| 新乡市| 平阴县| 吉安市| 广饶县| 阜新| 阳新县| 灵丘县| 白银市| 外汇| 洱源县| 木兰县| 林周县| 长丰县| 绍兴市| 确山县| 广平县| 北宁市| 广德县| 五华县| 蕉岭县| 盘山县| 确山县| 桂林市| 双流县| 连江县| 常州市| 绥芬河市| 安徽省| 梅河口市| 茌平县| 禄劝| 景德镇市| 丹东市| 澜沧| 辽源市| 曲水县|