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

資訊專欄INFORMATION COLUMN

Servlet 3.1 Async IO分析

n7then / 1034人閱讀

摘要:于是提供了機(jī)制,使得從中讀往里寫(xiě)變成異步動(dòng)作。這是因?yàn)榭蛻舳说臄?shù)據(jù)推送速度太慢了,容器先將收回,當(dāng)容器發(fā)現(xiàn)可以讀取到新數(shù)據(jù)的時(shí)候,再分配一個(gè)去讀,如此循環(huán)直到全部讀完為止。注意和不能同時(shí)使用。

Github地址

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

Servlet 3.0 異步處理詳解

Spring MVC異步處理的幾種方式

Servlet Async Processing提供了一種異步請(qǐng)求處理的手段(見(jiàn)我的另一篇文章Servlet 3.0 異步處理詳解),能夠讓你將Http thread從慢速處理中釋放出來(lái)出來(lái)其他請(qǐng)求,提高系統(tǒng)的響應(yīng)度。

但是光有Async Processing是不夠的,因?yàn)檎麄€(gè)請(qǐng)求-響應(yīng)過(guò)程的速度快慢還牽涉到了客戶端的網(wǎng)絡(luò)情況,如果客戶端網(wǎng)絡(luò)情況糟糕,其上傳和下載速度都很慢,那么同樣也會(huì)長(zhǎng)時(shí)間占用Http Thread使其不能被釋放出來(lái)。

于是Servlet 3.1提供了Async IO機(jī)制,使得從Request中讀、往Response里寫(xiě)變成異步動(dòng)作。

Async Read

我們先來(lái)一段客戶端上傳速度慢的例子,AsyncReadServlet.java:

@WebServlet(value = "/async-read", asyncSupported = true)
public class AsyncReadServlet extends HttpServlet {

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    System.out.println("Servlet thread: " + Thread.currentThread().getName());
    AsyncContext asyncCtx = req.startAsync();
    ServletInputStream is = req.getInputStream();
    is.setReadListener(new ReadListener() {
      private int totalReadBytes = 0;

      @Override
      public void onDataAvailable() {
        System.out.println("ReadListener thread: " + Thread.currentThread().getName());

        try {
          byte buffer[] = new byte[1 * 1024];
          int readBytes = 0;
          while (is.isReady() && !is.isFinished()) {
            int length = is.read(buffer);
            if (length == -1 && is.isFinished()) {
              asyncCtx.complete();
              System.out.println("Read: " + readBytes + " bytes");
              System.out.println("Total Read: " + totalReadBytes + " bytes");
              return;
            }
            readBytes += length;
            totalReadBytes += length;

          }
          System.out.println("Read: " + readBytes + " bytes");

        } catch (IOException ex) {
          ex.printStackTrace();
          asyncCtx.complete();
        }
      }

      @Override
      public void onAllDataRead() {
        try {
          System.out.println("Total Read: " + totalReadBytes + " bytes");
          asyncCtx.getResponse().getWriter().println("Finished");
        } catch (IOException ex) {
          ex.printStackTrace();
        }
        asyncCtx.complete();
      }

      @Override
      public void onError(Throwable t) {
        System.out.println(ExceptionUtils.getStackTrace(t));
        asyncCtx.complete();
      }
    });

  }

}

我們利用curl--limit-rate選項(xiàng)來(lái)模擬慢速上傳curl -X POST -F "bigfile=@src/main/resources/bigfile" --limit-rate 5k http://localhost:8080/async-read

然后觀察服務(wù)端的打印輸出:

Servlet thread: http-nio-8080-exec-3
ReadListener thread: http-nio-8080-exec-3
Read: 16538 bytes
ReadListener thread: http-nio-8080-exec-4
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-5
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-7
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-6
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-8
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-9
Read: 16384 bytes
ReadListener thread: http-nio-8080-exec-10
Read: 2312 bytes
ReadListener thread: http-nio-8080-exec-1
Read: 48 bytes
Total Read: 117202 bytes

可以從輸出看到除了doGet和第一次進(jìn)入onDataAvailable是同一個(gè)Http thread之外,后面的read動(dòng)作都發(fā)生在另外的Http thread里。
這是因?yàn)榭蛻舳说臄?shù)據(jù)推送速度太慢了,容器先將Http thread收回,當(dāng)容器發(fā)現(xiàn)可以讀取到新數(shù)據(jù)的時(shí)候,再分配一個(gè)Http thread去讀InputStream,如此循環(huán)直到全部讀完為止。

注意:HttpServletRequest.getInputStream()getParameter*()不能同時(shí)使用。

Async Write

再來(lái)一段客戶端下載慢的例子,AsyncWriteServlet.java:

@WebServlet(value = "/async-write", asyncSupported = true)
public class AsyncWriteServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    System.out.println("Servlet thread: " + Thread.currentThread().getName());
    AsyncContext asyncCtx = req.startAsync();
    ServletOutputStream os = resp.getOutputStream();
    InputStream bigfileInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("bigfile");

    os.setWriteListener(new WriteListener() {

      @Override
      public void onWritePossible() throws IOException {

        int loopCount = 0;
        System.out.println("WriteListener thread: " + Thread.currentThread().getName());
        while (os.isReady()) {
          loopCount++;
          System.out.println("Loop Count: " + loopCount);
          byte[] bytes = readContent();
          if (bytes != null) {
            os.write(bytes);
          } else {
            closeInputStream();
            asyncCtx.complete();
            break;
          }
        }
      }

      @Override
      public void onError(Throwable t) {

        try {
          os.print("Error happened");
          os.print(ExceptionUtils.getStackTrace(t));
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          closeInputStream();
          asyncCtx.complete();
        }

      }

      private byte[] readContent() throws IOException {
        byte[] bytes = new byte[1024];
        int readLength = IOUtils.read(bigfileInputStream, bytes);
        if (readLength <= 0) {
          return null;
        }
        return bytes;
      }

      private void closeInputStream() {
        IOUtils.closeQuietly(bigfileInputStream);
      }
    });

  }

}

同樣利用curl做慢速下載,curl --limit-rate 5k http://localhost:8080/async-write

接下來(lái)看以下服務(wù)端打印輸出:

Servlet thread: http-nio-8080-exec-1
WriteListener thread: http-nio-8080-exec-1
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-2
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-3
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-4
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-5
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-6
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-7
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-8
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-9
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-10
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-1
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-2
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-3
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-4
Write bytes: 8192
WriteListener thread: http-nio-8080-exec-5
Write bytes: 2312

PS. 后發(fā)現(xiàn)即使沒(méi)有添加--limit-rate參數(shù),也會(huì)出現(xiàn)類似于上面的結(jié)果。

Jmeter

上面兩個(gè)例子使用的是curl來(lái)模擬,我們也提供了Jmeter的benchmark。

需要注意的是,必須在user.properties文件所在目錄啟動(dòng)Jmeter,因?yàn)檫@個(gè)文件里提供了模擬慢速連接的參數(shù)httpclient.socket.http.cps=5120。然后利用Jmeter打開(kāi)benchmark.xml。

相關(guān)資料

Java EE 7 Tutorial: Java Servlet Technology - Nonblocking I/O

Slides - Servlet 3.1 Async IO

Non-blocking I/O using Servlet 3.1: Scalable applications using Java EE 7

How to simulate network bandwidth in JMeter?

Configuring JMeter

Servlet 3.1 Asynchronous IO and Jetty-9.1

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

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

相關(guān)文章

  • Spring MVC異步處理簡(jiǎn)介

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

    Sike 評(píng)論0 收藏0
  • Java Reactive Web設(shè)計(jì)與實(shí)現(xiàn)

    摘要:概念響應(yīng)式編程,異步非阻塞就是響應(yīng)式編程,與之相對(duì)應(yīng)的是命令式編程。的另外一種實(shí)現(xiàn)方式就是消息隊(duì)列。非阻塞設(shè)計(jì)利用規(guī)范中的實(shí)現(xiàn)實(shí)現(xiàn)代碼鏈接 注: 本文是由讀者觀看小馬哥公開(kāi)課視頻過(guò)程中的筆記整理而成。更多Spring Framework文章可參看筆者個(gè)人github: spring-framework-lesson 。 0. 編程模型與并發(fā)模型 Spring 5實(shí)現(xiàn)了一部分Reacti...

    siberiawolf 評(píng)論0 收藏0
  • Servlet 3.0 異步處理詳解

    摘要:但是這樣依然有一個(gè)問(wèn)題,考慮以下場(chǎng)景有一個(gè)容器,線程池大小。這個(gè)時(shí)候工程師發(fā)現(xiàn)了問(wèn)題,擴(kuò)展了線程池大小到,但是負(fù)載依然持續(xù)走高,現(xiàn)在有個(gè)到,依然無(wú)法響應(yīng)。你可以修改的線程池大小,把它和比較結(jié)果來(lái)驗(yàn)證這一結(jié)論。 Github地址 相關(guān)系列文章: Servlet 3.1 Async IO分析 Spring MVC異步處理的幾種方式 Servlet 3.0 開(kāi)始提供了AsyncConte...

    kid143 評(píng)論0 收藏0
  • AJAX入門(mén)這一篇就夠了

    摘要:性能會(huì)有所降低一點(diǎn)內(nèi)容,刷新整個(gè)頁(yè)面用戶的操作頁(yè)面會(huì)中斷整個(gè)頁(yè)面被刷新了就是能夠做到局部刷新三對(duì)象是中最重要的一個(gè)對(duì)象。頭信息已經(jīng)接收,響應(yīng)數(shù)據(jù)尚未接收。 一、什么是Ajax Ajax(Asynchronous JavaScript and XML) 異步JavaScript和XML Ajax實(shí)際上是下面這幾種技術(shù)的融合: (1)XHTML和CSS的基于標(biāo)準(zhǔn)的表示技術(shù) (2)DOM進(jìn)...

    tunny 評(píng)論0 收藏0
  • Servlet 常見(jiàn)的注解

    摘要:攔截所有的請(qǐng)求,放行登錄頁(yè)面登錄操作請(qǐng)求,其余請(qǐng)求需要在登錄后才可訪問(wèn)。同時(shí)配置參數(shù),指定要放行的路徑和請(qǐng)求的字符集。 Serlvet中WebServlet注解 作用: 用于將一個(gè)類聲明為 Servlet 描述: 該注解將會(huì)在部署時(shí)被容器處理, 容器將根據(jù)具體的屬性配置將相應(yīng)的類部署為 Servlet. 屬性詳解: 該注解具有下表給出的一些常用屬性(以下所有屬性均為可選屬性, 但是 v...

    hyuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<