Tomcat学习之线程模型(三)

Tomcat学习之线程模型

  • 种类
  • 配置方式
  • 概念介绍
    • 同步、异步
    • 阻塞、非阻塞
    • Java对BIO、NIO、AIO的支持
    • 使用场景
  • 线程模型
    • BIO
      • LimitLatch
    • NIO
  • 压测并发测试
    • Jmeter工具下载与使用
      • 1)下载
      • 2)解压
      • 3)使用
        • 1:新建线程组
        • 2:设置线程组参数
        • 3:新增http请求默认值
        • 4:添加要压测的http请求
        • 5:新增监听器,用于查看压测结果。
        • 6:运行
    • 压测结果

种类

tomcat一共有四种线程模型,如下:

名称 描述
BIO 阻塞式IO,采用传统的java IO进行操作,该模式下每个请求都会创建一个线程,适用于并发量小的环境
NIO 同步非阻塞,tomcat8.0后的默认模式
APR tomcat以JNI形式调用http服务器的核心动态链接库来处理文件读取和网络传输操作,需要编译安装APR库
AIO 异步非阻塞,tomcat8.0后支持

配置方式

默认的配置文件:

<Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
Service>

只要将protocol替换为以下几种即可:

BIO: protocol =" org.apache.coyote.http11.Http11Protocol" (tomcat9不支持)

NIO: protocol =“org.apache.coyote.http11.Http11NioProtocol”

AIO: protocol =“org.apache.coyote.http11.Http11Nio2Protocol”

APR: protocol =“org.apache.coyote.http11.Http11AprProtocol”

概念介绍

同步、异步

同步:自己亲自去买饭。(Java自己处理IO读写)

异步:点外卖,自己用走路去饭馆的时间去干别的事(Java将IO读写委托给操作系统处理,需要将数据缓冲区地址和大小传给操作系统(送餐地址,数量)

阻塞、非阻塞

阻塞:食堂排队,只能等待(使用阻塞IO是,Java调用会一直阻塞到读写完成才返回)。

非阻塞:取号,坐在位置上休息,等阿姨喊,同时可以询问是否轮到自己了(使用非阻塞IO时,如果不能读写,Java调用会马上返回,当IO事件分发器会通知可读写时再继续读写 ,不断循环到读写完成)。

Java对BIO、NIO、AIO的支持

Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理

使用场景

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

线程模型

BIO

Tomcat学习之线程模型(三)_第1张图片

启动时,JIoEndpoint组件内部的Acceptor组件将启动某个端口的监听,一个请求到来后将被扔进线程池Executor,线程池进行任务处理处理,处理过程中将通过Http11Processor组件对HTTP协议解析并传递到Engine容器继续处理。

LimitLatch

Tomcat的流量控制是通过AQS(AbstractQueuedSynchronizer)并发框架实现的,通过AQS实现更有灵活性和定制型。

LimitLatch用来控制tomcat的流量,每接收一个套接字(Socket)那么count+1,反之则减少 。如果超过最大限制,AQS将接收线程阻塞,停止接收套接字,直到某些套接字处理完关闭后重新唤起接收线程往下接收套接字。

Tomcat默认同时接收的客户端连接数为200,但可以通过server.xml中的节点的maxConnections进行调节,BIO模式下,最大连接数与最大线程数比例为1:1。

Tomcat学习之线程模型(三)_第2张图片
同时,与最大连接数相关的还有acceptCount参数,默认值为100。可以参考一下情形:

1)接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。

2)接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。

3)接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused。

NIO

Tomcat学习之线程模型(三)_第3张图片
与BIO相比,NIO多了Poller组件,它可以在非阻塞I/O方式下轮询多个客户端连接,不断检测,处理各种事件,例如不断检测各个连接是否可读,对于可读的客户端连接尝试进行读取并解析消息报文。

Tomcat学习之线程模型(三)_第4张图片
Poller池的大小应为:Math.min(2,Runtime.getRuntime().availableProcessors())

压测并发测试

Jmeter工具下载与使用

1)下载

打开Jmeter官网,进行工具的下载,http://jmeter.apache.org/download_jmeter.cgi

Tomcat学习之线程模型(三)_第5张图片

2)解压

解压到相应的目录后,以管理员的身份打开bin目录下的jmeter.bat。

Tomcat学习之线程模型(三)_第6张图片

启动后等待一段时间会弹出图形化界面:

Tomcat学习之线程模型(三)_第7张图片

3)使用

启动一个java web程序,开放端口localhost:8080,使用Jmeter对其进行压测,步骤如下:

1:新建线程组

Tomcat学习之线程模型(三)_第8张图片

2:设置线程组参数

Tomcat学习之线程模型(三)_第9张图片

3:新增http请求默认值

Tomcat学习之线程模型(三)_第10张图片

Tomcat学习之线程模型(三)_第11张图片

4:添加要压测的http请求

Tomcat学习之线程模型(三)_第12张图片

下图第一个红框内的协议、IP、端口不需要设置,会使用步骤3中设置的默认值,只需设置请求路径Path即可,这里填入/task2_1_war_exploded/hello,这是我的接口路径

Tomcat学习之线程模型(三)_第13张图片

5:新增监听器,用于查看压测结果。

Tomcat学习之线程模型(三)_第14张图片

6:运行

Tomcat学习之线程模型(三)_第15张图片

1)Label:每个 JMeter 的 element(例如 HTTP Request)都有一个 Name 属性,label显示的就是 Name 属性的值 。

2)#Samples:表示你这次测试中一共发出了多少个请求。

3)Average:平均响应时间——默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以Transaction 为单位显示平均响应时间。(单位ms)

4)Median:中位数,也就是 50% 用户的响应时间。

5)90% Line:90% 用户的响应时间。

6)Min:最小响应时间。

7)Max:最大响应时间。

8)Error%:本次测试中出现错误的请求的数量/请求的总数。

9)Throughput:吞吐量——默认情况下表示每秒完成的请求数(Request per Second),当使用了 Transaction Controller 时,也可以表示类似 LoadRunner 的 Transaction per Second 数。

10)KB/Sec:每秒从服务器端接收到的数据量,相当于LoadRunner中的Throughput/Sec 。

压测结果

tomcat模式 并发数 样本数 平均响应时间 吞吐量 错误率 接收Kb/s 发送Kb/s
nio 200 20000 147 1176.3/s 18.52% 817.18 134.78
nio 300 30000 236 1029.1/s 45.02% 1278.89 79.57
nio 500 50000 493 842.3/s 70.38% 1490.38 35.09
aio 200 20000 114 1357.1/s 18.70% 947.83 155.15
aio 300 30000 254 949.5/s 59.03% 1455.15 54.71
aio 500 50000 401 1020.9/s 64.70% 1687.59 50.68

可以发现两者性能差不多。同时可以发现,在当前配置下,并发数在200时(循环次数为100)就有点撑不住了。

你可能感兴趣的:(java学习,tomcat,线程模型,bio,nio,aio)