Skip to Content

在tomcat6的server.xml里边可以看到ajp和apr,nio相关配置信息。话说ajp1.3(Apache JServ Protocol)是定向包协议,跟http1.1那样是一种协议来的,使用二进制格式来传输可读性文本。如果WEB服务器通过TCP连接和servlet容器连接。为了减少进程生成 socket的花费,WEB服务器和servlet容器之间尝试保持持久性的TCP连接,对多个请求/回复循环重用一个连接。一旦连接分配给一个特定的请求,在请求处理循环结束之前不会在分配。换句话说,在连接上,请求不是多元的。这个是连接两端的编码变得容易,虽然这导致在一时刻会有很多连接。

  而APR(Apache Portable Runtime)是一个高可移植库,它是Apache HTTP Server 2.x的核心。包括访问高级IO功能(例如sendfile,epoll和OpenSSL),OS级别功能(随机数生成,系统状态等等),本地进程管理(共享内存,NT管道和UNIX sockets)。这些功能可以使Tomcat作为一个通常的前台WEB服务器,能更好地和其它本地web技术集成,总体上让Java更有效率作为一个高性能web服务器平台而不是简单作为后台容器。 所以呢,apr是可以和ajp,http结合使用的。

  nio(new io)又是什么,它早在jdk1.4就被引入了,一直以来好像也不是很多人关注这个。主要作用就是用来解决速度差异的。举个例子:计算机处理的速度和用户按键盘的速度。这两者的速度相差悬殊。如果按照经典的方法:一个用户设定一个线程,专门等待用户的输入,无形中就造成了严重的资源浪费:每一个线程都需要珍贵的cpu时间片,由于速度差异造成了在这个交互线程中的cpu都用来等待。这nio是怎么做的?无非就是非阻塞,谁要给谁,用模式话语就是观察者模式了。所以nio和ajp,http也是没冲突的。

  这么搞起来,io的方式就有apr,nio,普通io等,协议就有ajp,http等等,再加上带不带连接池什么什么的,在tomcat里边就有n多种io+protocol组合可供选择了。至于那种方式比较好,也没什么定论,nio也不一定比no好,要不早就流行了。以前也试过nio,性能反而下降了,还是要具体情况具体分析呀。tomcat6默认的配置是apr+http1.1,感觉这个配置还是相当合理的。呵,在这里也并不想比较哪个好点,只是希望有新同学再看到这些概念的时候不会乱了分寸。

浅析tomcat的nio配置

Tomcat 6.X实现了JCP的Servlet 2.5和JSP2.1的规范,并且包括其它很多有用的功能,使它成为开发

和部署web应用和web服务的坚实平台。

       NIO (No-blocking I/O)从JDK 1.4起,NIO API作为一个基于缓冲区,并能提供非阻塞I/O操作的API

被引入。

       作为开源web服务器的java实现,tomcat几乎就是web开发者开发、测试的首选,有很多其他商业服务

器的开发者也会优先选择tomcat作为开发时候使用,而在部署的时候,把应用发布在商业服务器上。也有

许多商业应用部署在tomcat上,tomcat承载着其核心的应用。但是很多开发者很迷惑,为什么在自己的应

用里使用tomcat作为平台的时候,而并发用户超过一定数量,服务器就变的非常繁忙,而且很快就出现了

connection refuse的错误。但是很多商业应用部署在tomcat上运行却安然无恙。

      其中有个很大的原因就是,配置良好的tomcat都会使用APR(Apache Portable Runtime),APR是

Apache HTTP Server2.x的核心,它是高度可移植的本地库,它使用高性能的UXIN I/O操作,低性能的

java io操作,但是APR对很多Java开发者而言可能稍稍有点难度,在很多OS平台上,你可能需要重新编

译APR。但是从Tomcat6.0以后, Java开发者很容易就可以是用NIO的技术来提升tomcat的并发处理能力。

但是为什么NIO可以提升tomcat的并发处理能力呢,我们先来看一下java 传统io与 java NIO的差别。

    

Java 传统的IO操作都是阻塞式的(blocking I/O), 如果有socket的编程基础,你会接触过堵塞socket和

非堵塞socket,堵塞socket就是在accept、read、write等IO操作的的时候,如果没有可用符合条件的资

源,不马上返回,一直等待直到有资源为止。而非堵塞socket则是在执行select的时候,当没有资源的时

候堵塞,当有符合资源的时候,返回一个信号,然后程序就可以执行accept、read、write等操作,一般来

说,如果使用堵塞socket,通常我们通常开一个线程accept socket,当读完这次socket请求的时候,开一

个单独的线程处理这个socket请求;如果使用非堵塞socket,通常是只有一个线程,一开始是select状,

当有信号的时候可以通过 可以通过多路复用(Multiplexing)技术传递给一个指定的线程池来处理请求,然

后原来的线程继续select状态。 最简单的多路复用技术可以通过java管道(Pipe)来实现。换句话说,如果

客户端的并发请求很大的时候,我们可以使用少于客户端并发请求的线程数来处理这些请求,而这些来不

及立即处理的请求会被阻塞在java管道或者队列里面,等待线程池的处理。请求 听起来很复杂,在这个架

构当道的java 世界里,现在已经有很多优秀的NIO的架构方便开发者使用,比如Grizzly,Apache Mina等

等,如果你对如何编写高性能的网络服务器有兴趣,你可以研读这些源代码。

      简单说一下,在web服务器上阻塞IO(BIO)与NIO一个比较重要的不同是,我们使用BIO的时候往往会

为每一个web请求引入多线程,每个web请求一个单独的线程,所以并发量一旦上去了,线程数就上去

了,CPU就忙着线程切换,所以BIO不合适高吞吐量、高可伸缩的web服务器;而NIO则是使用单线程(单

个CPU)或者只使用少量的多线程(多CPU)来接受Socket,而由线程池来处理堵塞在pipe或者队列里的请

求.这样的话,只要OS可以接受TCP的连接,web服务器就可以处理该请求。大大提高了web服务器的可

伸缩性。

    我们来看一下配置,你只需要在server.xml里把 HTTP Connector做如下更改,

    <Connector port=”8080″ protocol=”HTTP/1.1″

               connectionTimeout=”20000″

               redirectPort=”8443″ />

    改为

    <Connector port=”8080″ protocol=”org.apache.coyote.http11.Http11NioProtocol”

               connectionTimeout=”20000″

               redirectPort=”8443″ />

然后启动服务器,你会看到org.apache.coyote.http11.Http11NioProtocol start的信息,表示NIO已经启动。其他的配置请参考官方配置文档。

Enjoy it.

最后贴上官方文档上对tomcat的三种Connector的方式做一个简单比较,

   

转自:http://www.cnblogs.com/sunwei2012/archive/2010/03/05/1679299.html

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply