淺析tomcat nio 配置

来源:http://www.cnblogs.com/zzck/archive/2016/01/27/5162423.html
-Advertisement-
Play Games

【尊重原創文章摘自:http://blog.csdn.net/yaerfeng/article/details/7679740】tomcat的運行模式有3種.修改他們的運行模式.3種模式的運行是否成功,可以看他的啟動控制台,或者啟動日誌.或者登錄他們的預設頁面http://localhost:808...


【尊重原創文章摘自:http://blog.csdn.net/yaerfeng/article/details/7679740】

tomcat的運行模式有3種.修改他們的運行模式.3種模式的運行是否成功,可以看他的啟動控制台,或者啟動日誌.或者登錄他們的預設頁面http://localhost:8080/查看其中的伺服器狀態。

1)bio

預設的模式,性能非常低下,沒有經過任何優化處理和支持.

2)nio

利用java的非同步io護理技術,no blocking IO技術.

想運行在該模式下,直接修改server.xml里的Connector節點,修改protocol為

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

啟動後,就可以生效。

3)apr

安裝起來最困難,但是從操作系統級別來解決非同步的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照樣可以使用,不存在衝突。 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題:在MSSQLServer中定義的存儲過程可以直接返回一個數據集,如:create procedure sp_getAllEmployeesasSELECT * FROM [NORTHWND].[dbo].[Employees]在Oracle資料庫中這樣定義是錯誤的,怎麼解決?辦法:Oracle...
  • 12-5. 自動刪除相關聯實體問題當一個實體被刪除時,你想自動刪除它相關聯的實體解決方案假設你有一個表結構由一個course (科目), course 的classes (課程),以及enrollment (登記學生選課),如 Figure 12-5所示:.Figure 12-5. The Cour...
  • 需求:工廠類根據參數生成對應類的實例。示例:RoomParts.csnamespace ReflectionFactory{ /// /// 屋子產品的零件 /// public enum RoomParts { Roof, Window...
  • Control:1 public ActionResult GetPositionName(int parentid) //發佈新職位頁面中的根據職位類別,獲取職位名稱2 {3 List categorylist2 = categorymanage.G...
  • 實現反射的類型大多數都定義在System.Reflection命名空間之下。Assembly 定義一個Assembly,它是可重用、無版本衝突並且可自我描述的公共語言運行庫應用程式構造塊。AssemblyName 完整描述程式集的唯一標識EventInfo 發現事件的屬性(Attribute)...
  • Web大前端時代之:HTML5+CSS3入門系列:http://www.cnblogs.com/dunitian/p/5121725.html 定位類型 IP 定位 優點 任何位置都可用 在伺服器端處理 缺點 不精確,一般精確到城市 運算代價大,可能出錯 代理的時候就可能定位出錯了 GPS定位 優點...
  • 2016.1.27|A1∪A2∪…∪Am| = (1≤i≤m)∑|Ai| - (1≤i<j≤m)∑|Ai∩Aj| + (1≤i<j<k≤m)∑|Ai∩Aj∩Ak | - … + (-1)m-1|A1∩A2∩…∩Am|就是這東西,沒什麼好說的,不大懂的話取個較小的m試一下文氏圖就好,至於證明,出門右轉...
  • 一、背景在學習函數之前,一直遵循:面向過程編程,即:根據業務邏輯從上到下實現功能,其往往用一長段代碼來實現指定功能,開發過程中最常見的操作就是粘貼複製,也就是將之前實現的代碼塊複製到現需功能處,如下while True: if cpu利用率 > 90%: #發送郵件提醒 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...