Tomcat学习之线程模型(三)

种类

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

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

配置方式

默认的配置文件:web

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

只要将protocol替换为如下几种便可:apache

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

NIO: protocol ="org.apache.coyote.http11.Http11NioProtocol"tomcat

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

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

LimitLatch

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

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

Tomcat默认同时接收的客户端链接数为200,但能够经过server.xml中的<Connector>节点的maxConnections进行调节,BIO模式下,最大链接数与最大线程数比例为1:1。

同时,与最大链接数相关的还有 acceptCount参数,默认值为100。能够参考一下情形:

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

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

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

NIO

与BIO相比,NIO多了Poller组件,它能够在非阻塞I/O方式下轮询多个客户端链接,不断检测,处理各类事件,例如不断检测各个链接是否可读,对于可读的客户端链接尝试进行读取并解析消息报文。

Poller池的大小应为: Math.min(2,Runtime.getRuntime().availableProcessors())

压测并发测试

Jmeter工具下载与使用

1)下载

打开Jmeter官网,进行工具的下载,jmeter.apache.org/download_jm…

2)解压

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

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

3)使用

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

1:新建线程组

2:设置线程组参数

3:新增http请求默认值

4:添加要压测的http请求

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

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

6:运行

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)就有点撑不住了。

相关文章
相关标签/搜索