11.11活动当天,服务器负载过大,致使部分页面出现了不可访问的状态、那后来主管就要求调优了,下面是tomcat bio、nio、apr模式以及后来本身测试的一些性能结果。java
原理方面的资料都是从网上找的,而且把多个地方的整理到了一块儿,以为颇有意义。(后面对tomcat默认页面测试的数据是本身测出来的),tomcat 的三种模式若是用对了场合,性能绝对有大幅度的提高。固然调优也并不仅在这一个方面,还有内存(堆内存、非堆内存、新生代内存)以及线程(最大线程、请求队列、备用线程、压缩、以及禁用dns轮询)等方面。linux
那在作tomcat bio nio apr 模式以前,先来了解下 java 的一些特性吧。nginx
Java BIO、NIO、AIOweb
同步 : 本身亲自出马持银行卡到银行取钱(使用同步IO时,Java本身处理IO读写)。apache
异步 : 委托一小弟拿银行卡到银行取钱,而后给你(使用异步IO时,Java将IO读写委托给OS处理,须要将数据缓冲区地址和大小传给OS(银行卡和密码),OS须要支持异步IO操做API)。编程
阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回)。vim
非阻塞 : 柜台取款,取个号,而后坐在椅子上作其它事,等号广播会通知你办理,没到号你就不能去,你能够不断问大堂经理排到了没有,大堂经理若是说还没到你就不能去(使用非阻塞IO时,若是不能读写Java调用会立刻返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。后端
Java对BIO、NIO、AIO的支持:tomcat
Java BIO : 同步并阻塞,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善。bash
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回收频繁使性能达到一个最优的结果。固然,这也须要根据不一样的场合进行不一样的测试才能产生最优的结果!