淺析Tomcat NIO 配置
Tomcat 6.X實(shí)現(xiàn)了JCP的Servlet 2.5和JSP2.1的規(guī)范,并且包括其它很多有用的功能,使它成為開發(fā)和部署web應(yīng)用和web服務(wù)的堅(jiān)實(shí)平臺(tái)。
NIO (No-blocking I/O)從JDK 1.4起,NIO API作為一個(gè)基于緩沖區(qū),并能提供非阻塞I/O操作的API被引入。
作為開源web服務(wù)器的java實(shí)現(xiàn),tomcat幾乎就是web開發(fā)者開發(fā)、測試的***,有很多其他商業(yè)服務(wù)器的開發(fā)者也會(huì)優(yōu)先選擇tomcat作為開發(fā)時(shí)候使用,而在部署的時(shí)候,把應(yīng)用發(fā)布在商業(yè)服務(wù)器上。也有許多商業(yè)應(yīng)用部署在tomcat上,tomcat承載著其核心的應(yīng)用。但是很多開發(fā)者很迷惑,為什么在自己的應(yīng)用里使用tomcat作為平臺(tái)的時(shí)候,而并發(fā)用戶超過一定數(shù)量,服務(wù)器就變的非常繁忙,而且很快就出現(xiàn)了connection refuse的錯(cuò)誤。但是很多商業(yè)應(yīng)用部署在tomcat上運(yùn)行卻安然無恙。
其中有個(gè)很大的原因就是,配置良好的tomcat都會(huì)使用APR(Apache Portable Runtime),APR是Apache HTTP Server2.x的核心,它是高度可移植的本地庫,它使用高性能的UXIN I/O操作,低性能的java io操作,但是APR對(duì)很多Java開發(fā)者而言可能稍稍有點(diǎn)難度,在很多OS平臺(tái)上,你可能需要重新編譯APR。但是從Tomcat6.0以后, Java開發(fā)者很容易就可以是用NIO的技術(shù)來提升tomcat的并發(fā)處理能力。
但是為什么NIO可以提升tomcat的并發(fā)處理能力呢,我們先來看一下java 傳統(tǒng)io與 java NIO的差別。
Java 傳統(tǒng)的IO操作都是阻塞式的(blocking I/O), 如果有socket的編程基礎(chǔ),你會(huì)接觸過堵塞socket和非堵塞socket,堵塞socket就是在accept、read、write等IO操作的的時(shí)候,如果沒有可用符合條件的資源,不馬上返回,一直等待直到有資源為止。而非堵塞socket則是在執(zhí)行select的時(shí)候,當(dāng)沒有資源的時(shí)候堵塞,當(dāng)有符合資源的時(shí)候,返回一個(gè)信號(hào),然后程序就可以執(zhí)行accept、read、write等操作,一般來說,如果使用堵塞socket,通常我們通常開一個(gè)線程accept socket,當(dāng)讀完這次socket請(qǐng)求的時(shí)候,開一個(gè)單獨(dú)的線程處理這個(gè)socket請(qǐng)求;如果使用非堵塞socket,通常是只有一個(gè)線程,一開始是select狀,當(dāng)有信號(hào)的時(shí)候可以通過 可以通過多路復(fù)用(Multiplexing)技術(shù)傳遞給一個(gè)指定的線程池來處理請(qǐng)求,然后原來的線程繼續(xù)select狀態(tài)。 最簡單的多路復(fù)用技術(shù)可以通過java管道(Pipe)來實(shí)現(xiàn)。換句話說,如果客戶端的并發(fā)請(qǐng)求很大的時(shí)候,我們可以使用少于客戶端并發(fā)請(qǐng)求的線程數(shù)來處理這些請(qǐng)求,而這些來不及立即處理的請(qǐng)求會(huì)被阻塞在java管道或者隊(duì)列里面,等待線程池的處理。請(qǐng)求 聽起來很復(fù)雜,在這個(gè)架構(gòu)當(dāng)?shù)赖膉ava 世界里,現(xiàn)在已經(jīng)有很多優(yōu)秀的NIO的架構(gòu)方便開發(fā)者使用,比如Grizzly,Apache Mina等等,如果你對(duì)如何編寫高性能的網(wǎng)絡(luò)服務(wù)器有興趣,你可以研讀這些源代碼。
簡單說一下,在web服務(wù)器上阻塞IO(BIO)與NIO一個(gè)比較重要的不同是,我們使用BIO的時(shí)候往往會(huì)為每一個(gè)web請(qǐng)求引入多線程,每個(gè)web請(qǐng)求一個(gè)單獨(dú)的線程,所以并發(fā)量一旦上去了,線程數(shù)就上去了,CPU就忙著線程切換,所以BIO不合適高吞吐量、高可伸縮的web服務(wù)器;而NIO則是使用單線程(單個(gè)CPU)或者只使用少量的多線程(多CPU)來接受Socket,而由線程池來處理堵塞在pipe或者隊(duì)列里的請(qǐng)求.這樣的話,只要OS可以接受TCP的連接,web服務(wù)器就可以處理該請(qǐng)求。大大提高了web服務(wù)器的可伸縮性。
我們來看一下配置,你只需要在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" />
然后啟動(dòng)服務(wù)器,你會(huì)看到org.apache.coyote.http11.Http11NioProtocol start的信息,表示NIO已經(jīng)啟動(dòng)。其他的配置請(qǐng)參考官方配置文檔。
Enjoy it.
***貼上官方文檔上對(duì)tomcat的三種Connector的方式做一個(gè)簡單比較。
Java Nio Blocking Connector | Java Nio Blocking Connector | APR Connector | |
Classname | Http11Protocol | Http11NioProtocol | Http11AprProtocol |
Tomcat Version | 3.x 4.x 5.x 6.x | 6.x | 5.5.x 6.x |
Support Polling | NO | YES | YES |
Polling Size | N/A | Unlimited - Restricted by mem | Unlimited |
Read HTTP Request | Blocking | Blocking | Blocking |
Read HTTP Body | Blocking | Blocking | Blocking |
Write HTTP Response | Blocking | Blocking | Blocking |
SSL Support | Java SSL | Java SSL | OpenSSL |
SSL Handshake | Blocking | Non blocking | Blocking |
Max Connections | maxThreads | See polling size | See polling size |
原文鏈接:http://northc.iteye.com/blog/1290186
【編輯推薦】