tomcat BIO 、NIO 、AIO
11.11活动当天,服务器负载过大,导致部分页面出现了不可访问的状态、那后来主管就要求调优了,下面是tomcat bio、nio、apr模式以及后来自己测试的一些性能结果。
原理方面的资料都是从网上找的,并且把多个地方的整理到了一起,觉得很有意义。(后面对tomcat默认页面测试的数据是自己测出来的),tomcat 的三种模式如果用对了场合,性能绝对有大幅度的提升。当然调优也并不只在这一个方面,还有内存(堆内存、非堆内存、新生代内存)以及线程(最大线程、请求队列、备用线程、压缩、以及禁用dns轮询)等方面。
那在做tomcat bio nio apr 模式之前,先来了解下 java 的一些特性吧。
Java BIO、NIO、AIO
同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写)。
异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API)。
阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回)。
非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。
Java对BIO、NIO、AIO的支持:
Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理
BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
好,下面来看看tomcat 的 bio、nio、apr 模式
bio
bio(blocking I/O),顾名思义,即阻塞式I/O操作,表示Tomcat使用的是传统的Java I/O操作(即java.io包及其子包)。Tomcat在默认情况下,就是以bio模式运行的。遗憾的是,就一般而言,bio模式是三种运行模式中性能最低的一种。我们可以通过Tomcat Manager来查看服务器的当前状态。
nio
是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性能。
apr
(Apache Portable Runtime/Apache可移植运行库),是Apache HTTP服务器的支持库。你可以简单地理解为,Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat对静态文件的处理性能。 Tomcat apr也是在Tomcat上运行高并发应用的首选模式。
在这之前,我们先把tomcat管理界面配置起来,以便等下能更方便的观察我们的bio、nio、apr 模式
添加manager/status用户
vim /usr/local/apache-tomcat-7.0.47/conf/tomcat-users.xml
<role rolename="manager-gui"/>
<user username="tomcat" password="15715746746" roles="manager-gui"/>
配置完重启,通过ip:port/manager/status 就可以看tomcat状态了,里面有服务器的信息及tomcat信息。
bio server.xml 配置 (重启生效)
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
nio server.xml 配置 (重启生效)
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
apr server.xml 配置 (重启生效)
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
redirectPort="8443" />
当然,apr模式还需要安装 apr 、 apr-utils 、tomcat-native包
apr 安装
tar zxf apr-1.5.2.tar.gz -C /usr/local/src/
cd /usr/local/src/apr-1.5.2/
./configure --prefix=/usr/local/apr && make && make install
apr-utils 安装
tar zxf apr-util-1.5.4.tar.gz -C /usr/local/src/
cd /usr/local/src/apr-util-1.5.4/
./configure --with-apr=/usr/local/apr/ --prefix=/usr/local/apr-utils && make && make install
tomcat-native安装
cd /usr/local/apache-tomcat-7.0.65/bin/
tar zxf tomcat-native.tar.gz
cd tomcat-native-1.1.33-src/jni/native
./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/java/ && make && make install
安装完后记得在 /etc/profile 的JAVA变量后面多加一条APR的环境变量
设置环境变量
JAVA_HOME=/usr/local/java
JAVA_BIN=$JAVA_HOME/bin
PATH=$PATH:$JAVA_BIN
CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JAVA_BIN PATH CLASSPATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
source /etc/profile
那下面来看看 apr 的页面
到这里大致的配置就结束了,建议在做实验之前,先了解清楚java的 bio 、nio 、aio特性,在web服务器上阻塞IO(BIO)与NIO一个比较重要的不同是,客户系统使用BIO的时候往往会为每一个web请求引入多线程,每个web请求一个单独的线程,所以并发量一旦上去了,线程数就上去了,CPU就忙着线程切换,所以BIO不合适高吞吐量、高可伸缩的web服务器;而NIO则是使用单线程(单个CPU)或者只使用少量的多线程(多CPU)来接受Socket,而由线程池来处理堵塞在pipe或者队列里的请求.这样的话,只要OS可以接受TCP的连接,web服务器就可以处理该请求。大大提高了web服务器的可伸缩性。
下面是我自己的一些性能测试表格,通过jmeter压测软件(jmeter软件使用自行百度)在本地测试的(为了数据的有效以及准确性,我没测试10分钟,也就是进行一次测试,都会重启linux主机及重新打开jmeter软件。),当然你也可以选择通过 云主机、自己机房的服务器以及虚拟机等测试,测试当中会涉及到很多点,例如(磁盘io、带宽、内存、cpu、以及内核配置中的tcp各种状态,甚至是各种打开文件限制,都会影响到我们的测试结果)
可以看到,随着线程的不断增多,bio 模式性能越来越差,就算是在本地,错误率和响应时间都在明显的增加、而吞吐量、样本数和每秒传输速率都在下降(当然,如果是生产环境,我们肯定通过nginx web 软件进行反向代理,提供多个tomcat 节点来提供更稳定的服务。)
而 bio 和 apr模式基本上没有变化太多,都保持在一个稳定的状态。
而后来当我进行一些 service 后端程序的测试时,发现 tomcat 性能并没有大幅度的提升,甚至会有下降的趋势。(该接口不是在同网段测试,而是跨越路由器,在网络传输中会有损耗方面,性能跟本地测试也会有所差异)
总结:
个人觉得在 tomcat bio、nio、apr 模式中,每种都会有各自适用的场合,也不能说哪个好那个不好,就像 tomcat 内存方面的配置,如果内存设置的过大,gc 垃圾回收机制就会变慢;如果内存设置的过小,tomcat又会出现内存溢出的情况,所以设置在一个合适的范围很重要,不仅不会出错,并且gc回收频繁使性能达到一个最优的结果。当然,这也需要根据不同的场合进行不同的测试才能产生最优的结果!
tomcat BIO 、NIO 、AIO的更多相关文章
- Tomcat在Linux服务器上的BIO、NIO、APR模式设置
一.BIO.NIO.AIO 先了解四个概念: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时, ...
- Java网络通信方面,BIO、NIO、AIO、Netty
码云项目源码地址:https://gitee.com/ZhangShunHai/echo 教学视频地址:链接: https://pan.baidu.com/s/1knVlW7O8hZc8XgXm1dC ...
- Java中的IO、NIO、File、BIO、AIO详解
java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包 ...
- 京东数科二面:常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?
IO 模型这块确实挺难理解的,需要太多计算机底层知识.写这篇文章用了挺久,就非常希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇文章,还翻看了一下<UNIX 网络编程>这本书,太 ...
- 京东数科面试真题:常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?
本文节选自<Java面试进阶指北 打造个人的技术竞争力> 面试中经常喜欢问的一个问题,因为通过这个问题,面试官可以顺便了解一下你的操作系统的水平. IO 模型这块确实挺难理解的,需要太多计 ...
- Java BIO、NIO、AIO 学习(转)
转自 http://stevex.blog.51cto.com/4300375/1284437 先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Ja ...
- AIO、NIO、BIO
AIO:异步非阻塞 NIO:同步非阻塞 BIO:同步阻塞 (1)同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 (2)异步 指用户进程触发IO操作以后便开始做自己的事情,而当I ...
- BIO与NIO、AIO的区别
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Serve ...
- JAVA中IO技术:BIO、NIO、AIO
1.同步异步.阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作 ...
随机推荐
- 洛谷 - P1072 Hankson - 的趣味题 - 质因数分解
https://www.luogu.org/problemnew/show/P1072 一开始看了一看居然还想放弃了的. 把 \(x,a_0,a_1,b_0,b_1\) 质因数分解. 例如 \(x=p ...
- 结合 webpack 使用 vue-router(七)
结合 webpack 使用 vue-router: 首先安装路由包vue-router: cnpm install vue-router 使用模块化工具导入 vue-router 后,必须手动调用 V ...
- time库的使用
首先只需要 import time (典型的,标准的python库的使用方法) 主要包括三类函数 ——时间获取:time() , ctime() , gmtime() ——时间格式化: strftim ...
- TYVJ 2032 搜索
P2032 「Poetize9」升降梯上 描述 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升降的巨 ...
- 洛谷 P3957 跳房子
https://www.luogu.org/problemnew/show/P3957 错误记录:1.没开longlong 2. -inf不够小 #include<cstdio> #inc ...
- Jasper_crosstab_group_dataset_Error incrementing crosstab dataset
Error detail: net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRRuntimeExceptio ...
- 552 Student Attendance Record II 学生出勤记录 II
给定一个正整数 n,返回长度为 n 的所有可被视为可奖励的出勤记录的数量. 答案可能非常大,你只需返回结果mod 109 + 7的值.学生出勤记录是只包含以下三个字符的字符串: 1.'A' : ...
- MVC 下载相关
前台: location.href = "/Flow/SB1SP?clxxid=8099b23c-aa5a-44a3-97ef-85eed78145ba"; 后台: publci ...
- Mysql->order by SQL 根据多个条件排序
Mysql中根据多个条件排序:(各个条件间使用逗号隔开) 首先根据class_name字符串长短升序排列,然后根据开始时间降序排列: SELECT * FROM signup_class s OR ...
- ES6中新增的字符串方法
实例方法:includes(), startsWith(), endsWith() 传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中.ES6 又提供 ...