Tomcat配置NIO

tomcat的運行模式有3種.修改他們的運行模式.3種模式的運行是否成功,能夠看他的啓動控制檯,或者啓動日誌.或者登陸他們的默認頁面http://localhost:8080/查看其中的服務器狀態。html

1)biojava

默認的模式,性能很是低下,沒有通過任何優化處理和支持.web

2)nio 數據庫

利用java的異步io護理技術,no blocking IO技術.apache

想運行在該模式下,直接修改server.xml裏的Connector節點,修改protocol爲編程

 <Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" 
	connectionTimeout="20000" 
	URIEncoding="UTF-8" 
	useBodyEncodingForURI="true" 
	enableLookups="false" 
	redirectPort="8443" /> 

啓動後,就能夠生效。windows

3)apr tomcat

安裝起來最困難,可是從操做系統級別來解決異步的IO問題,大幅度的提升性能.服務器

必需要安裝apr和native,直接啓動就支持apr。下面的修改純屬多餘,僅供你們擴充知識,但仍然須要安裝apr和native網絡

如nio修改模式,修改protocol爲org.apache.coyote.http11.Http11AprProtocol

 

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的方式作一個簡單比較,
   

Java 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
 
 
若是讀者有socket的編程基礎,應該會接觸過堵塞socket和非堵塞socket,堵塞socket就是在accept、read、write等IO操做的的時候,若是沒有可用符合條件的資源,不立刻返回,一直等待直到有資源爲止。而非堵塞socket則是在執行select的時候,當沒有資源的時候堵塞,當有符合資源的時候,返回一個信號,而後程序就能夠執行accept、read、write等操做,這個時候,這些操做是立刻完成,而且立刻返回。而windows的winsock則有所不一樣,能夠綁定到一個EventHandle裏,也能夠綁定到一個HWND裏,當有資源到達時,發出事件,這時執行的io操做也是立刻完成、立刻返回的。通常來講,若是使用堵塞socket,一般咱們時開一個線程accept socket,當有socket連接的時候,開一個單獨的線程處理這個socket;若是使用非堵塞socket,一般是隻有一個線程,一開始是select狀態,當有信號的時候立刻處理,而後繼續select狀態。 
   
  按照大多數人的說法,堵塞socket比非堵塞socket的性能要好。不過也有小部分人並非這樣認爲的,例如Indy項目(Delphi一個比較出色的網絡包),它就是使用多線程+堵塞socket模式的。另外,堵塞socket比非堵塞socket容易理解,符合通常人的思惟,編程相對比較容易。      nio其實也是相似上面的狀況。在JDK1.4,sun公司大範圍提高Java的性能,其中NIO就是其中一項。Java的IO操做集中在java.io這個包中,是基於流的阻塞API(即BIO,Block IO)。對於大多數應用來講,這樣的API使用很方便,然而,一些對性能要求較高的應用,尤爲是服務端應用,每每須要一個更爲有效的方式來處理IO。從JDK 1.4起,NIO API做爲一個基於緩衝區,並能提供非阻塞O操做的API(即NIO,non-blocking IO)被引入。      BIO與NIO一個比較重要的不一樣,是咱們使用BIO的時候每每會引入多線程,每一個鏈接一個單獨的線程;而NIO則是使用單線程或者只使用少許的多線程,每一個鏈接共用一個線程。      這個時候,問題就出來了:咱們很是多的java應用是使用ThreadLocal的,例如JSF的FaceContext、Hibernate的session管理、Struts2的Context的管理等等,幾乎全部框架都或多或少地應用ThreadLocal。若是存在衝突,那豈不驚天動地?      後來終於在Tomcat6的文檔(http://tomcat.apache.org/tomcat-6.0-doc/aio.html)找到答案。根據上面說明,應該Tomcat6應用nio只是用在處理髮送、接收信息的時候用到,也就是說,tomcat6仍是傳統的多線程Servlet,我畫了下面兩個圖來列出區別:      tomcat5:客戶端鏈接到達 -> 傳統的SeverSocket.accept接收鏈接 -> 從線程池取出一個線程 -> 在該線程讀取文本而且解析HTTP協議 -> 在該線程生成ServletRequest、ServletResponse,取出請求的Servlet -> 在該線程執行這個Servlet -> 在該線程把ServletResponse的內容發送到客戶端鏈接 -> 關閉鏈接。      我之前理解的使用nio後的tomcat6:客戶端鏈接到達 -> nio接收鏈接 -> nio使用輪詢方式讀取文本而且解析HTTP協議(單線程) -> 生成ServletRequest、ServletResponse,取出請求的Servlet -> 直接在本線程執行這個Servlet -> 把ServletResponse的內容發送到客戶端鏈接 -> 關閉鏈接。      實際的tomcat6:客戶端鏈接到達 -> nio接收鏈接 -> nio使用輪詢方式讀取文本而且解析HTTP協議(單線程) -> 生成ServletRequest、ServletResponse,取出請求的Servlet -> 從線程池取出線程,並在該線程執行這個Servlet -> 把ServletResponse的內容發送到客戶端鏈接 -> 關閉鏈接。           從上圖能夠看出,BIO與NIO的不一樣,也致使進入客戶端處理線程的時刻有所不一樣:tomcat5在接受鏈接後立刻進入客戶端線程,在客戶端線程裏解析HTTP協議,而tomcat6則是解析完HTTP協議後才進入多線程,另外,tomcat6也比5早脫離客戶端線程的環境。      實際的tomcat6與我以前猜測的差異主要集中在如何處理servlet的問題上。實際上即便拋開ThreadLocal的問題,我以前理解tomcat6只使用一個線程處理的想法實際上是行不一樣的。你們都有經驗:servlet是基於BIO的,執行期間會存在堵塞的,例如讀取文件、數據庫操做等等。tomcat6使用了nio,但不可能要求servlet裏面要使用nio,而一旦存在堵塞,效率天然會銳降。          因此,最終的結論固然是tomcat6的servlet裏面,ThreadLocal照樣可使用,不存在衝突。 
http://www.cnblogs.com/sunwei2012/archive/2010/03/05/1679299.html
相關文章
相關標籤/搜索