PHP: 開發語言:腳本語言 運行環境:解釋執行 Zend Engine:Opcode Xcache,APC,eAccelerator MVC: data:數據 bussiness:業務 presentation:展示 C/C++:CPU,OS 移植困難 維護成本高 高速 驅動 oak:橡樹,智能, java: 包含四個獨立卻又彼此相關的技術: Java程序設計語言 Java API Java Class文件格式 JVM:Java Virtual Machine JVM的實現方式: 1.一次解釋器,解釋字節碼并執行 2.即時編譯器(just-in-time complier) 依賴于更多內存緩存解釋后的結果 3.自適應編譯器 緩存20%左右代碼,提高80%左右的速度 Java設計語言:Sun Java API: JVM:Hotspot JVM JRE:java運行時環境 運行 JDK:java開發環境 開發(編譯)+運行 JVM:OpenJDK 開發+運行 開源實現 Java API類庫 第三方類庫 JDK=Java+API+JVM,是用于實現Java程序開發的最小環境 JRE=JVM+java SE API Java應用領域的不同,Java可分為三類: JAVA SE:Standard Edtion JAVA EE:Enterprise Edition,J2EE JAVA ME:Mobile Edtion,J2ME 1995年,JAVA 1.0面世, James Gosling, Green Project applet:小程序 動態網站 CGI:Common Gateway Interface 協議 HTML
applet, servlet, jsp JSP: .jsp --> .java -->(JVM) .class JDK: javac, .java --> .class CGI, Servlet, .java Web Servlet Container: Servlet容器 Web Container: Web容器 線程私有內存區: 程序計數器 java虛擬機棧 線程共享內存區: 方法區 堆:java自動內存回收,GC(Garbage Collector) 垃圾回收算法: 1、標記-清除 2、復制 二分之一 3、標記-整理 垃圾回收器: Serial ParNew Parallel Scavenge Serial Old Parallel Old CMS: Concurrent Mark Sweep 特點:并發收集、低停頓 缺點:無法浮動垃圾、由于基于標記-清除會產生碎片 G1 安裝: rpm 通用二進制格式, .bin 源碼
vim /etc/profile.d/java.sh export JAVA_HOME=/usr/java/jdk1.6.0_21 export PATH=$PATH:$JAVA_HOME/bin . /etc/profile.d/java.sh
java配置參數: -XX:+
類的生命周期: Loading:加載 Verification:驗證 Preparation:準備 Resolutin:解析 Initilization:初始化 Using:使用 Unloading:卸載
Sun JDK監控和故障處理工具: jps, JVM Process Status Tool: 顯示指定系統內所有的HotSpot虛擬機進程的列表信息 jstat, JVM Statistics Monitoring Tool:收集并顯示HotSpot虛擬機各方面的運行數據 jinfo:顯示正在運行的某HotSpot虛擬機配置信息 jmap: 生成某HotSpot虛擬機的內存轉儲快照; 可視化工具: jconsole: Java的監控與管理控制臺 jvisualvm:
Tomcat系列之組件詳解及服務安裝配置
Servlet: CGI, java 硬編碼, html JSP: <% %>, html Jasper, .jsp --> .java JSP --> Servlet
容器類組件: Engine, Host, Context 頂級組件: Server, Service Realm(領域): 用戶帳號數據庫 Valve(閥門): 記錄訪問日志 基于IP認證 Logger: 日志記錄器
常見的web容器有: 商業版: ◇ Sun GlassFish Enterprise Server ◇ Sun Java System Web Server ◇ JBoss Enterprise Application Platform ◇ WebLogic Application Server ◇ Caucho's Resin Server ◇ WebSphere Application Server ◇ NetWeaver 非商業版: ◇ Apache Tomcat ◇ Apache Geronimo ◇ GlassFish ◇ JBoss Application Server ◇ Jetty ◇ Tiny Java Web Server ◇ Eclipse Virgo server.xml: Tomcat各組件間的關系:默認的, 應用程序部署描述符 部署:將一個web應用程序所依賴到的類裝載進JVM
Tomcat系列之apache使用mod_jk和mod_proxy反向代理
添加一個新的Host: 編輯server.xml:
<%@ page language="java" %>
TomcatA
<% session.setAttribute("abc","abc"); %>
Session ID | <%= session.getId() %> |
Created on | <%= session.getCreationTime() %> |
192.168.10.8:8080/
Java體系結構包括四個獨立但相關的技術: Java程序設計語言 Java class文件格式 Java API Java VM 用Java語言編譯源代碼,把它編譯成Java Class文件,然后在Java VM中運行class文件;當編寫程序時,通過調用類(Java API)中的方法來訪問系統資源,而當程序運行時,它通過調用class文件中實現了Java API的方法也滿足程序的Java API調用。Java VM和Java API一起組成了一個“平臺”,所有Java程序都在其上編譯和運行,因此,它們有時也被稱作Java運行時環境。 Java VM的主要任務是裝載class文件并且執行其中的字節碼。Java VM包含一個類裝載器(class loader),它可以從程序和API裝載class文件;而Java API的類只在程序執行中需要時才會被裝載。 Java字節碼由執行引擎來執行。而不同的Java VM中,其執行引擎的實現可能各不相同。最簡單的執行引擎不是一次性解釋字節碼,而另一種稱為“即時編譯器(just-in-time compiler)”的執行引擎執行速度更快,但要消耗更多的內存資源。即時編譯模式下,第一次被執行的字節碼會被編譯成本地機器代碼并緩存下來以實現“復用”。第三種執行引擎是所謂的自適應優化器,此種方法中,虛擬機始的時候解釋字節碼,介是會監視運行中程序的活動,并且記錄下使用最頻繁的代碼。程序運行時,虛擬機只把那些活動最頻繁的代碼編譯成本地代碼,而不頻繁的代碼則仍然保留為字節碼由虛擬機解釋執行。自適應優化器可以使得Java VM在80%-90%的時間里執行被優化過的本地代碼,而只需要編譯10%-20%對性能有影響的代碼。最后一種虛擬機由硬件芯片構成,它用本地方法執行Java字節碼,其執行引擎內嵌于芯片中。 Sun公司創建了第一個Servlet容器,即Java Web Server, 但JWS只是為了演示Servlet的相應功能,所以其很不穩定。與此同時,ASF創建了JServ項目,一個能夠與apache整合起來的servlet容器。1999年,Sun把JWS捐給了ASF,于是兩個項目合二為一,即今天Tomcat的前身。第一個tomcat版本是Tomcat 3.x系列,而發布于2001年Tomcat4.0則是在此前基礎上進行了重新設計和實現,其代碼項目被命名為Catalina。目前最新的版本則是7.x系列。 Java SE則包含了Java二進制程序(如JVM和Java字節碼編譯器)和Java的核心代碼庫,而Jave EE標準則包含了一組適用于創建企業級Web應用程序的API。Jave EE建立在Java SE的基礎上,并依賴于Java SE才能正常工作。當然,任何級別的應用程序均能從Java EE中獲益,但Jave EE卻更適合解決大型軟件系統設計中的問題。 JAVA EE包含多個獨立的API,Servlet和JSP就是其中的兩個,而JAVA EE中著名的API中還包含如下的幾個: JAVA EE APIs: EJB(Enterprise JavaBeans):JAVA相關的諸多高級功能的實現,如RMI(Remote Method Invocation), 對象/關系映射,跨越多個數據源的分布式事務等; JMS(Java Message Service):高性能異步消息服務,實現JAVA EE應用程序與非JAVA程序的“透明”通信; JMX(Java Management Extensions):在程序運行時對其進行交互式監控和管理的機制; JTA(Java Transaction API):允許應用程序在自身的一個或多個組件中平滑地處理錯誤的機制; JavaMail:通過工業標準的POP/SMTP/IMAP協議發送和接收郵件的機制; Java SE APIs: JNDI(Java Naming and Directory Interface):用于與LDAP服務交互的API; JAXP(Java API for XML Processing):用于分析及轉換XML(基于XSLT實現); Java SE API + JDK JAVA EE Application Servers: Websphere Weblogic oc4j JBoss JOnAS Geronimo Glassfish risen Sun --> TWS RI: Reference Implimentation 參考實現 ASF:Apache Software Foundation Jserv Sun --> ASF catalina O'Reilly: Tomcat 男貓 類,.jar JVM, Tomcat: Servlet and JSP APIs, JNDI and JMX APIs. Tomcat不是一個完整意義上的Jave EE服務器,它甚至都沒有提供對哪怕是一個主要Java EE API的實現;但由于遵守apache開源協議,tomcat卻又為眾多的java應用程序服務器嵌入自己的產品中構建商業的java應用程序服務器,如JBoss和JOnAS。 盡管Tomcat對Jave EE API的實現并不完整,然而很企業也在漸漸拋棄使用傳統的Java EE技術(如EJB)轉而采用一些開源組件來構建復雜的應用。這些開源組件如Structs、Spring和Hibernate,而Tomcat能夠對這些組件實現完美的支持。 HTTP是一種無狀態的協議,在用戶的一次連接請求響應完成后,服務器端將無法識別在后續的連接請求中再次識別此用戶,交將其所有請求關聯起來。為了解決這個問題,java container通過一個臨時的cookie來為此用戶保存一個標識,此標識即所謂的用戶session。 在第一次調用之后,JSP會被編譯成一個servlet類,在后續的操作中則可以直接使用此類,從而避免了對每一次調用的都要重新分析和編譯。因此,類似servlet,JSP的執行需要在container中完成。JSP的container跟servlet的container基本相同,但在JSP執行之前,需要一些額外的步驟如與servlet代碼建立會話等。Tomcat包含了一個叫做Catalina的Servlet container(執行servlet和編譯過的JSP)和一個JSP編譯器(Jasper編譯器)。事實上,一個包含了JSP編譯器和Servlet容器的應用程序組合通過被稱作Web容器。 JSP和Servlet的最大區別在于,Servlet通常需要事先編譯好,而JSP則并非必須事先編譯。這意味著Servlet通常放置于私有資源區域,而JSP則通常以嵌入代碼的方式包含于HTML頁面文件中,這些HTML文件通常放置在公開資源區域。 MVC架構: Controller,Model和View各自獨立,一個流行的開源實現是Apache Structs框架;目今,設計優良的Web應用程序通常用相就的技術實現相應的功能,比如: 1、Servlet用于實現應用邏輯; 2、JSP用于內容展示; 3、標簽庫和JSP擴展語言用于替換在JSP內部嵌入Java代碼,進而降低了HTML維護的復雜度; 4、MVC框架用于實現展示和應用邏輯的分離; 對于一個Web應用程序而言,其通常由Servlets、JSP和其它文件等共同組成。這些文件通常被打包成WAR(Web Application Archive)格式,并以.war作為打包后的文件擴展名。而Servlet規范則定義了在WAR內部組織這些文件的標準目錄結構。其目錄和功用如下: / Web應用程序的根目錄,所有可被公開訪問的文件均放置于此處,如HTML、JSP和圖片文件等; /WEB-INF 此目錄為私有資源目錄,其內部的所有文件和子目錄均不能被公開訪問;包含著此Web應用程序的配置文件web.xml(程序結構描述符文件)通常放置于此目錄; /WEB-INF/classes 當前Web應用程序的類文件的存在目錄; /WEB-INF/lib 可被打包為JAR格式的類文件通常放置于此目錄; 安裝tomcat: 一、先安裝JVM 二、安裝配置tomcat A Tomcat init script for Linux #!/bin/sh # Tomcat init script for Linux. # # chkconfig: 2345 96 14 # description: The Apache Tomcat servlet/JSP container. JAVA_HOME=/usr/java/jdk1.7.0_05 CATALINA_HOME=/opt/apache-tomcat-7.0.29 export JAVA_HOME CATALINA_HOME exec $CATALINA_HOME/bin/catalina.sh $* Tomcat的架構: Tomcat 6支持Servlet 2.5和JSP 2.1的規范,它由一組嵌套的層次和組件組成,一般可分為以下四類: 頂級組件:位于配置層次的頂級,并且彼此間有著嚴格的對應關系; 連接器:連接客戶端(可以是瀏覽器或Web服務器)請求至Servlet容器, 容器:包含一組其它組件; 被嵌套的組件:位于一個容器當中,但不能包含其它組件; 各常見組件: 1、服務器(server):Tomcat的一個實例,通常一個JVM只能包含一個Tomcat實例;因此,一臺物理服務器上可以在啟動多個JVM的情況下在每一個JVM中啟動一個Tomcat實例,每個實例分屬于一個獨立的管理端口。這是一個頂級組件。 2、服務(service):一個服務組件通常包含一個引擎和與此引擎相關聯的一個或多個連接器。給服務命名可以方便管理員在日志文件中識別不同服務產生的日志。一個server可以包含多個service組件,但通常情下只為一個service指派一個server。 連接器類組件: 3、連接器(connectors):負責連接客戶端(可以是瀏覽器或Web服務器)請求至Servlet容器內的Web應用程序,通常指的是接收客戶發來請求的位置及服務器端分配的端口。默認端口通常是HTTP協議的8080,管理員也可以根據自己的需要改變此端口。一個引擎可以配置多個連接器,但這些連接器必須使用不同的端口。默認的連接器是基于HTTP/1.1的Coyote。同時,Tomcat也支持AJP、JServ和JK2連接器。 容器類組件: 4、引擎(Engine):引擎通是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它檢查每一個請求的HTTP首部信息以辨別此請求應該發往哪個host或context,并將請求處理后的結果返回的相應的客戶端。嚴格意義上來說,容器不必非得通過引擎來實現,它也可以是只是一個容器。如果Tomcat被配置成為獨立服務器,默認引擎就是已經定義好的引擎。而如果Tomcat被配置為Apache Web服務器的提供Servlet功能的后端,默認引擎將被忽略,因為Web服務器自身就能確定將用戶請求發往何處。一個引擎可以包含多個host組件。 5、主機(Host):主機組件類似于Apache中的虛擬主機,但在Tomcat中只支持基于FQDN的“虛擬主機”。一個引擎至少要包含一個主機組件。 6、上下文(Context):Context組件是最內層次的組件,它表示Web應用程序本身。配置一個Context最主要的是指定Web應用程序的根目錄,以便Servlet容器能夠將用戶請求發往正確的位置。Context組件也可包含自定義的錯誤頁,以實現在用戶訪問發生錯誤時提供友好的提示信息。 被嵌套類(nested)組件: 這類組件通常包含于容器類組件中以提供具有管理功能的服務,它們不能包含其它組件,但有些卻可以由不同層次的容器各自配置。 7、閥門(Valve):用來攔截請求并在將其轉至目標之前進行某種處理操作,類似于Servlet規范中定義的過濾器。Valve可以定義在任何容器類的組件中。Valve常被用來記錄客戶端請求、客戶端IP地址和服務器等信息,這種處理技術通常被稱作請求轉儲(request dumping)。請求轉儲valve記錄請求客戶端請求數據包中的HTTP首部信息和cookie信息文件中,響應轉儲valve則記錄響應數據包首部信息和cookie信息至文件中。 8、日志記錄器(Logger):用于記錄組件內部的狀態信息,可被用于除Context之外的任何容器中。日志記錄的功能可被繼承,因此,一個引擎級別的Logger將會記錄引擎內部所有組件相關的信息,除非某內部組件定義了自己的Logger組件。 9、領域(Realm):用于用戶的認證和授權;在配置一個應用程序時,管理員可以為每個資源或資源組定義角色及權限,而這些訪問控制功能的生效需要通過Realm來實現。Realm的認證可以基于文本文件、數據庫表、LDAP服務等來實現。Realm的效用會遍及整個引擎或頂級容器,因此,一個容器內的所有應用程序將共享用戶資源。同時,Realm可以被其所在組件的子組件繼承,也可以被子組件中定義的Realm所覆蓋。 引擎(Engine):引擎是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它從HTTPconnector接收請求并響應請求。它檢查每一個請求的HTTP首部信息以辨別此請求應該發往哪個host或context,并將請求處理后的結果返回的相應的客戶端。嚴格意義上來說,容器不必非得通過引擎來實現,它也可以是只是一個容器。如果Tomcat被配置成為獨立服務器,默認引擎就是已經定義好的引擎。而如果Tomcat被配置為Apache Web服務器的提供Servlet功能的后端,默認引擎將被忽略,因為Web服務器自身就能確定將用戶請求發往何處。一個引擎可以包含多個host組件。 Tomcat連接器架構: 基于Apache做為Tomcat前端的架構來講,Apache通過mod_jk、mod_jk2或mod_proxy模塊與后端的Tomcat進行數據交換。而對Tomcat來說,每個Web容器實例都有一個Java語言開發的連接器模塊組件,在Tomcat6中,這個連接器是org.apache.catalina.Connector類。這個類的構造器可以構造兩種類別的連接器:HTTP/1.1負責響應基于HTTP/HTTPS協議的請求,AJP/1.3負責響應基于AJP的請求。但可以簡單地通過在server.xml配置文件中實現連接器的創建,但創建時所使用的類根據系統是支持APR(Apache Portable Runtime)而有所不同。 APR是附加在提供了通用和標準API的操作系統之上一個通訊層的本地庫的集合,它能夠為使用了APR的應用程序在與Apache通信時提供較好伸縮能力時帶去平衡效用。 同時,需要說明的是,mod_jk2模塊目前已經不再被支持了,mod_jk模塊目前還apache被支持,但其項目活躍度已經大大降低。因此,目前更常用 的方式是使用mod_proxy模塊。 如果支持APR: 1、HTTP/1.1:org.apache.cotote.http11.Http11AprProtocol 2、AJP/1.3:org.apache.coyote.ajp.AjpAprProtocol 如果不支持APR: HTTP/1.1: org.apache.coyote.http11.Http11Protocol AJP/1.3: org.apache.jk.server.JkCoyoteHandler 連接器協議: Tomcat的Web服務器連接器支持兩種協議:AJP和HTTP,它們均定義了以二進制格式在Web服務器和Tomcat之間進行數據傳輸,并提供相應的控制命令。 AJP(Apache JServ Protocol)協議: 目前正在使用的AJP協議的版本是通過JK和JK2連接器提供支持的AJP13,它基于二進制的格式在Web服務器和Tomcat之間傳輸數據,而此前的版本AJP10和AJP11則使用文本格式傳輸數據。 HTTP協議:誠如其名稱所表示,其是使用HTTP或HTTPS協議在Web服務器和Tomcat之間建立通信,此時,Tomcat就是一個完全功能的HTTP服務器,它需要監聽在某端口上以接收來自于商前服務器的請求。 Tomcat的配置文件: Tomcat的配置文件默認存放在$CATALINA_HOME/conf目錄中,主要有以下幾個: server.xml: Tomcat的主配置文件,包含Service, Connector, Engine, Realm, Valve, Hosts主組件的相關配置信息; web.xml:遵循Servlet規范標準的配置文件,用于配置servlet,并為所有的Web應用程序提供包括MIME映射等默認配置信息; tomcat-user.xml:Realm認證時用到的相關角色、用戶和密碼等信息;Tomcat自帶的manager默認情況下會用到此文件;在Tomcat中添加/刪除用戶,為用戶指定角色等將通過編輯此文件實現; catalina.policy:Java相關的安全策略配置文件,在系統資源級別上提供訪問控制的能力; catalina.properties:Tomcat內部package的定義及訪問相關的控制,也包括對通過類裝載器裝載的內容的控制;Tomcat6在啟動時會事先讀取此文件的相關設置; logging.properties: Tomcat6通過自己內部實現的JAVA日志記錄器來記錄操作相關的日志,此文件即為日志記錄器相關的配置信息,可以用來定義日志記錄的組件級別以及日志文件的存在位置等; context.xml:所有host的默認配置信息; 一、server.xml Tomcat以面向對象的方式運行,它可以在運行時動態加載配置文件中定義的對象結構,這有點類似于apache的httpd模塊的調用方式。server.xml中定義的每個主元素都會被創建為對象,并以某特定的層次結構將這些對象組織在一起。下面是個樣樣例配置:server.xml文件中可定義的元素非常多,包括Server, Service, Connector, Engine, Cluster, Host, Alias, Context, Realm, Valve, Manager, Listener, Resources, Resource, ResourceEnvRef, ResourceLink, WatchedResource, GlobalNameingResources, Store, Transaction, Channel, Membership, Transport, Member, ClusterListener等。 下面簡單介紹幾個常用組件: 1、Server組件 如上面示例文件中定義的: 這會讓Tomcat6啟動一個server實例(即一個JVM),它監聽在8005端口以接收shutdown命令。各Server的定義不能使用同一個端口,這意味著如果在同一個物理機上啟動了多個Server實例,必須配置它們使用不同的端口。這個端口的定義用于為管理員提供一個關閉此實例的便捷途徑,因此,管理員可以直接telnet至此端口使用SHUTDOWN命令關閉此實例。不過,基于安全角度的考慮,這通常不允許遠程進行。 Server的相關屬性: className: 用于實現此Server容器的完全限定類的名稱,默認為org.apache.catalina.core.StandardServer; port: 接收shutdown指令的端口,默認僅允許通過本機訪問,默認為8005; shutdown:發往此Server用于實現關閉tomcat實例的命令字符串,默認為SHUTDOWN; 2、Service組件: Service主要用于關聯一個引擎和與此引擎相關的連接器,每個連接器通過一個特定的端口和協議接收入站請求交將其轉發至關聯的引擎進行處理。困此,Service要包含一個引擎、一個或多個連接器。 如上面示例中的定義: 這定義了一個名為Catalina的Service,此名字也會在產生相關的日志信息時記錄在日志文件當中。 Service相關的屬性: className: 用于實現service的類名,一般都是org.apache.catalina.core.StandardService。 name:此服務的名稱,默認為Catalina; 3、Connector組件: 進入Tomcat的請求可以根據Tomcat的工作模式分為如下兩類: Tomcat作為應用程序服務器:請求來自于前端的web服務器,這可能是Apache, IIS, Nginx等; Tomcat作為獨立服務器:請求來自于web瀏覽器; Tomcat應該考慮工作情形并為相應情形下的請求分別定義好需要的連接器才能正確接收來自于客戶端的請求。一個引擎可以有一個或多個連接器,以適應多種請求方式。 定義連接器可以使用多種屬性,有些屬性也只適用于某特定的連接器類型。一般說來,常見于server.xml中的連接器類型通常有4種: 1) HTTP連接器 2) SSL連接器 3) AJP 1.3連接器 4) proxy連接器 如上面示例server.xml中定義的HTTP連接器: 定義連接器時可以配置的屬性非常多,但通常定義HTTP連接器時必須定義的屬性只有“port”,定義AJP連接器時必須定義的屬性只有"protocol",因為默認的協議為HTTP。以下為常用屬性的說明: 1) address:指定連接器監聽的地址,默認為所有地址,即0.0.0.0; 2) maxThreads:支持的最大并發連接數,默認為200; 3) port:監聽的端口,默認為0; 4) protocol:連接器使用的協議,默認為HTTP/1.1,定義AJP協議時通常為AJP/1.3; 5) redirectPort:如果某連接器支持的協議是HTTP,當接收客戶端發來的HTTPS請求時,則轉發至此屬性定義的端口; 6) connectionTimeout:等待客戶端發送請求的超時時間,單位為毫秒,默認為60000,即1分鐘; 7) enableLookups:是否通過request.getRemoteHost()進行DNS查詢以獲取客戶端的主機名;默認為true; 8) acceptCount:設置等待隊列的最大長度;通常在tomcat所有處理線程均處于繁忙狀態時,新發來的請求將被放置于等待隊列中; 下面是一個定義了多個屬性的SSL連接器: 4、Engine組件: Engine是Servlet處理器的一個實例,即servlet引擎,默認為定義在server.xml中的Catalina。Engine需要defaultHost屬性來為其定義一個接收所有發往非明確定義虛擬主機的請求的host組件。如前面示例中定義的: 常用的屬性定義: defaultHost:Tomcat支持基于FQDN的虛擬主機,這些虛擬主機可以通過在Engine容器中定義多個不同的Host組件來實現;但如果此引擎的連接器收到一個發往非非明確定義虛擬主機的請求時則需要將此請求發往一個默認的虛擬主機進行處理,因此,在Engine中定義的多個虛擬主機的主機名稱中至少要有一個跟defaultHost定義的主機名稱同名; name:Engine組件的名稱,用于日志和錯誤信息記錄時區別不同的引擎; Engine容器中可以包含Realm、Host、Listener和Valve子容器。 5、Host組件: 位于Engine容器中用于接收請求并進行相應處理的主機或虛擬主機,如前面示例中的定義: 常用屬性說明: 1) appBase:此Host的webapps目錄,即存放非歸檔的web應用程序的目錄或歸檔后的WAR文件的目錄路徑;可以使用基于$CATALINA_HOME的相對路徑; 2) autoDeploy:在Tomcat處于運行狀態時放置于appBase目錄中的應用程序文件是否自動進行deploy;默認為true; 3) unpackWars:在啟用此webapps時是否對WAR格式的歸檔文件先進行展開;默認為true; 虛擬主機定義示例: 主機別名定義: 如果一個主機有兩個或兩個以上的主機名,額外的名稱均可以以別名的形式進行定義,如下: 6、Context組件: Context在某些意義上類似于apache中的路徑別名,一個Context定義用于標識tomcat實例中的一個Web應用程序;如下面的定義: magedu.com 在Tomcat6中,每一個context定義也可以使用一個單獨的XML文件進行,其文件的目錄為$CATALINA_HOME/conf/ / 。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。 常用的屬性定義有: 1) docBase:相應的Web應用程序的存放位置;也可以使用相對路徑,起始路徑為此Context所屬Host中appBase定義的路徑;切記,docBase的路徑名不能與相應的Host中appBase中定義的路徑名有包含關系,比如,如果appBase為deploy,而docBase絕不能為deploy-bbs類的名字; 2) path:相對于Web服務器根路徑而言的URI;如果為空“”,則表示為此webapp的根路徑;如果context定義在一個單獨的xml文件中,此屬性不需要定義; 3) reloadable:是否允許重新加載此context相關的Web應用程序的類;默認為false; 7、Realm組件: 一個Realm表示一個安全上下文,它是一個授權訪問某個給定Context的用戶列表和某用戶所允許切換的角色相關定義的列表。因此,Realm就像是一個用戶和組相關的數據庫。定義Realm時惟一必須要提供的屬性是classname,它是Realm的多個不同實現,用于表示此Realm認證的用戶及角色等認證信息的存放位置。 JAASRealm:基于Java Authintication and Authorization Service實現用戶認證; JDBCRealm:通過JDBC訪問某關系型數據庫表實現用戶認證; JNDIRealm:基于JNDI使用目錄服務實現認證信息的獲取; MemoryRealm:查找tomcat-user.xml文件實現用戶信息的獲取; UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)實現用戶認證,它實現是一個完全可更新和持久有效的MemoryRealm,因此能夠跟標準的MemoryRealm兼容;它通過JNDI實現; 下面是一個常見的使用UserDatabase的配置: 下面是一個使用JDBC方式獲取用戶認證信息的配置: mysql://localhost/authority" debug="99" drivername="org.gjt.mm.mysql.Driver" rolenamecol="role_name" usercredcol="user_pass" usernamecol="user_name" userroletable="user_roles" usertable="users"> 8、Valve組件: Valve類似于過濾器,它可以工作于Engine和Host/Context之間、Host和Context之間以及Context和Web應用程序的某資源之間。一個容器內可以建立多個Valve,而且Valve定義的次序也決定了它們生效的次序。Tomcat6中實現了多種不同的Valve: AccessLogValve:訪問日志Valve ExtendedAccessValve:擴展功能的訪問日志Valve JDBCAccessLogValve:通過JDBC將訪問日志信息發送到數據庫中; RequestDumperValve:請求轉儲Valve; RemoteAddrValve:基于遠程地址的訪問控制; RemoteHostValve:基于遠程主機名稱的訪問控制; SemaphoreValve:用于控制Tomcat主機上任何容器上的并發訪問數量; JvmRouteBinderValve:在配置多個Tomcat為以Apache通過mod_proxy或mod_jk作為前端的集群架構中,當期望停止某節點時,可以通過此Valve將用記請求定向至備用節點;使用此Valve,必須使用JvmRouteSessionIDBinderListener; ReplicationValve:專用于Tomcat集群架構中,可以在某個請求的session信息發生更改時觸發session數據在各節點間進行復制; SingleSignOn:將兩個或多個需要對用戶進行認證webapp在認證用戶時連接在一起,即一次認證即可訪問所有連接在一起的webapp; ClusterSingleSingOn:對SingleSignOn的擴展,專用于Tomcat集群當中,需要結合ClusterSingleSignOnListener進行工作; RemoteHostValve和RemoteAddrValve可以分別用來實現基于主機名稱和基于IP地址的訪問控制,控制本身可以通過allow或deny來進行定義,這有點類似于Apache的訪問控制功能;如下面的Valve則實現了僅允許本機訪問/probe: 其中相關屬性定義有: 1) className:相關的java實現的類名,相應于分別應該為org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve; 2) allow:以逗號分開的允許訪問的IP地址列表,支持正則表達式,因此,點號“.”用于IP地址時需要轉義;僅定義allow項時,非明確allow的地址均被deny; 3) deny: 以逗號分開的禁止訪問的IP地址列表,支持正則表達式;使用方式同allow; 9、GlobalNamingResources 應用于整個服務器的JNDI映射,此可以避免每個Web應用程序都需要在各自的web.xml創建,這在web應用程序以WAR的形式存在時尤為有用。它通常可以包含三個子元素: 1) Environment; 2) Resource; 3) ResourceEnvRef; 10、WatchedResource WatchedResource可以用于Context中監視指定的webapp程序文件的改變,并且能夠在監視到文件內容發生改變時重新裝載此文件。 11、Listener Listener用于創建和配置LifecycleListener對象,而LifecycleListener通常被開發人員用來創建和刪除容器。 11、Loader Java的動態裝載功能是其語言功能強大表現之一,Servlet容器使用此功能在運行時動態裝載servlet和它們所依賴的類。Loader可以用于Context中控制java類的加載。 12、Manager Manger對象用于實現HTTP會話管理的功能,Tomcat6中有5種Manger的實現: 1) StandardManager Tomcat6的默認會話管理器,用于非集群環境中對單個處于運行狀態的Tomcat實例會話進行管理。當Tomcat關閉時,這些會話相關的數據會被寫入磁盤上的一個名叫SESSION.ser的文件,并在Tomcat下次啟動時讀取此文件。 2) PersistentManager 當一個會話長時間處于空閑狀態時會被寫入到swap會話對象,這對于內存資源比較吃緊的應用環境來說比較有用。 3)DeltaManager 用于Tomcat集群的會話管理器,它通過將改變了會話數據同步給集群中的其它節點實現會話復制。這種實現會將所有會話的改變同步給集群中的每一個節點,也是在集群環境中用得最多的一種實現方式。 4) BackupManager 用于Tomcat集群的會話管理器,與DeltaManager不同的是,某節點會話的改變只會同步給集群中的另一個而非所有節點。 5)SimpleTcpReplicationManager Tomcat4時用到的版本,過于老舊了。 13、Stores PersistentManager必須包含一個Store元素以指定將會話數據存儲至何處。這通常有兩種實現方式:FileStore和JDBCStore。 14、Resources 經常用于實現在Context中指定需要裝載的但不在Tomcat本地磁盤上的應用資源,如Java類,HTML頁面,JSP文件等。 15、Cluster 專用于配置Tomcat集群的元素,可用于Engine和Host容器中。在用于Engine容器中時,Engine中的所有Host均支持集群功能。在Cluster元素中,需要直接定義一個Manager元素,這個Manager元素有一個其值為org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className屬性。同時,Cluster中還需要分別定義一個Channel和ClusterListener元素。 15.1、Channel 用于Cluster中給集群中同一組中的節點定義通信“信道”。Channel中需要至少定義Membership、Receiver和Sender三個元素,此外還有一個可選元素Interceptor。 15.2、Membership 用于Channel中配置同一通信信道上節點集群組中的成員情況,即監控加入當前集群組中的節點并在各節點間傳遞心跳信息,而且可以在接收不到某成員的心跳信息時將其從集群節點中移除。Tomcat6中Membership的實現是org.apache.catalina.tribes.membership.McastService。 15.3、Sender 用于Channel中配置“復制信息”的發送器,實現發送需要同步給其它節點的數據至集群中的其它節點。發送器不需要屬性的定義,但可以在其內部定義一個Transport元素。 15.4 Transport 用于Sender內部,配置數據如何發送至集群中的其它節點。Tomcat6有兩種Transport的實現: 1) PooledMultiSender 基于Java阻塞式IO,可以將一次將多個信息并發發送至其它節點,但一次只能傳送給一個節點。 2)PooledParallelSener 基于Java非阻塞式IO,即NIO,可以一次發送多個信息至一個或多個節點。 15.5 Receiver 用于Channel定義某節點如何從其它節點的Sender接收復制數據,Tomcat6中實現的接收方式有兩種BioReceiver和NioReceiver。 二、web.xml文件 web.xml基于Java Servlet規范,可被用于每一個Java servlet容器,通常有兩個存放位置,$CATALINA_BASE/conf和每個Web應用程序(通常是WEB-INF/web.xml)。Tomcat在deploy一個應用程序時(包括重啟或重新載入),它首先讀取conf/web.xml,而后讀取WEB-INF/web.xml。 啟用manager功能: 編輯tomcat-user.xml,添加如下行: 而后重啟tomcat。 啟用host-manager和server status功能: startup腳本: #!/bin/sh # Tomcat init script for Linux. # # chkconfig: 2345 96 14 # description: The Apache Tomcat servlet/JSP container. JAVA_OPTS='-Xms64m -Xmx128m' JAVA_HOME=/usr/java/jdk1.7.0_05 CATALINA_HOME=/usr/local/apache-tomcat-7.0.29 export JAVA_HOME CATALINA_HOME exec $CATALINA_HOME/bin/catalina.sh $* APR即Apache Portable Runtime,原來是apache2的一個庫,后來被獨立成了一個項目。基于此庫文件,Tomcat可以表現出更好的穩定性和性能,尤其是Tomcat作為apache的后端Servlet容器時。 事先安裝apr-devel包,而后編譯安裝tomcat的APR JNI。安裝方法如下: # cd $CATALINA_HOME/bin # tar xf tomcat-native.tar.gz # cd tomcat-native-1.1.22-src/jni/native/ # ./configure --with-apr=/usr --with-ssl --with-apxs # make && make install # echo "/usr/local/apr/lib/" > /etc/ld.so.conf.d/apr.conf # ldconfig 應用程序: jforum java center home 配置tomcat啟用Manager Manager的四個管理角色: manager-gui - allows access to the HTML GUI and the status pages manager-script - allows access to the text interface and the status pages manager-jmx - allows access to the JMX proxy and the status pages manager-status - allows access to the status pages only 添加一個新的Host: 編輯server.xml: 列出所有Deployed的Web應用程序: http://{ hostname }:{ portnumber }/manager/list Tomcat的連接器分為兩類:HTTP連接器和Web服務器連接器。 Tomcat的HTTP連接器有三種: 1) 基于java的HTTP/1.1連接器,這也是Tomcat6默認使用的連接器,即Coyote;它是Tomcat作為standalone模式工作時所用到的連接器,可直接響應來自用戶瀏覽器的關于JSP、servlet和HTML的請求;此連接器是一個Java類,定義在server.xml當中,默認使用8080端口; 2) Java開發的高性能NIO HTTP/1.1連接器,它支持非阻塞式IO和Comnet,在基于庫向tomcat發起請求時,此連接器表現不俗;但其實現不太成熟,有嚴重bug存在; 3) C/C++開發的native APR HTTP/1.1連接器;在負載較大的場景中,此連接器可以提供非常好的性能;APR即Apache Portable Runtime,它是一個能讓開發者采用與平臺無關的風格的方式來開發C/C++代碼本地庫,它能夠很好的跨Windows, Linux和*nix平臺工作。此連接器從三個主要方面優化了系統性能并提升了系統的伸縮能力:(1)使用sendfile()內核模式調用發送大的靜態文件;(2) 僅使用一個native code保持大量的連接;(3) 使用能夠加速SSL請求處理的OpenSSL本地代碼; 啟用APR連接器的條件: 1) 將連接器的protocol屬性設定為org.apache.coyote.http11.Http11AprProtocol; 2) APR的庫文件已經在系統庫文件的搜索路徑內; 基于連接器提供Tomcat6性能的方法: 1) 設置tcpNoDelay屬性值為“true”; 2) 通過maxKeepAliveRequest屬性調整允許keep-alive功能的請求的最大數目,值為1時表示禁用; 3) 調整socketBuffer屬性的值以改變套接字緩沖的大小; 4) 將enableLookups設置為false以禁用DNS反解; 5) Tomcat是一個多線程的Servlet容器,使用線程池能對服務器性能帶去很大影響;這主要通過maxThreads、maxSpareThreads和minSpareThreads來定義; 6) 通過JAVA_OPTS,如-Xms和-Xmx設定JVM相關的參數以定義其使用內存的能力; AJP(Apache JServ Protocol): AJP是面向數據包的基于TCP/IP的協議,它在Apache和Tomcat的實例之間提供了一個專用的通信信道。目前常用AJP協議的版本是1.3,它主要有以下特征: 1) 在快速網絡有著較好的性能表現,支持數據壓縮傳輸; 2) 支持SSL,加密及客戶端證書; 3) 支持Tomcat實例集群; 4) 支持在apache和tomcat之間的連接的重用; Apache可以通過mod_jk和mod_proxy模塊跟Tomcat整合,但mod_proxy只有在apache 2.2.x系列的版本才直接提供,但它可以提供更豐富的功能和安全性;而對于apache 1.3.x和2.0.x來說mod_jk才更適用。 配置apache通過mod_proxy模塊與Tomcat連接: 1、檢測當前的apache是否支持mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module模塊: # httpd -D DUMP_MODULES …………………… proxy_module (shared) proxy_balancer_module (shared) proxy_ftp_module (shared) proxy_http_module (shared) proxy_connect_module (shared) …………………… 2、在httpd.conf的全局配置段或虛擬主機中添加如下內容: ProxyVia On ProxyRequests Off ProxyPreserveHost On Order deny,allow Allow from all ProxyPass /examples/jsp ajp://172.16.100.1:8009/examples/jsp ProxyPassReverse /examples/jsp ajp://172.16.100.1:8009/examples/jspOrder allow,deny Allow from all 配置apache和tomcat一起工作: 1、編譯安裝apache: # ./configure --prefix=/usr/local/apache --enable-proxy --enable-proxy-http --enable-proxy-ajp 2、配置apache加載相應的模塊: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so 3、配置apache代理tomcat: 第一種方法,基于proxy-http: ProxyPass /my-webapp http://www.magedu.com:8080/my-webapp ProxyPassReverse /my-webapp http://www.magedu.com:8080/my-webapp ProxyVia On 第二種方法,基于proxy-ajp: ProxyPass /my-webapp ajp://tomcathost:8009/my-webapp ProxyPassReverse /my-webapp ajp://tomcathost:8009/my-webapp ProxyVia On 4、確保tomcat配置有如上使用的連接器; tar xf httpd-2.4.2 cd httpd-2.4.2 ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --enable-proxy --enable-proxy-http --enable-proxy-ajp make && make install tar xf tomcat-connectors-1.2.37-src.tar.gz cd tomcat-connectors-1.2.37-src/native/ ./configure --with-apxs=/usr/local/apache/bin/apxs make && make install server端session: 1、service向用戶瀏覽器發送cookie,此cookie包含獲取服務端session的標識。 2、向用戶通過瀏覽器請求同一站點的頁面時,相應的cookie信息會隨之發送。 3、server從cookie信息中識別出與此瀏覽器相關的session標識,從而判別出當前server上此瀏覽器的session信息。 在用戶瀏覽器不支持cookie的場景中,也可以基于URL重寫實現session功能。簡單來講就是server端通過為任何一個響應給用戶的URL附加上session id的方式來標識用戶請求。 不過需要注意的是,每個瀏覽器進程都會各自管理各自跟服務端的會話ID,因此,在服務器端看來,同一個客戶端上的多個瀏覽器進程會被識別成不同的客戶端。 2012年7月7號: Tomcat7的配置文件(conf目錄中): catalina.policy: Tomcat7的安全策略,用于JVM強制將安全策略施加于Webapp; catalina.properties: Tomcat啟動時會掃描此文件,它包括共享的server、shared loader及JAR等; server.xml: 主配置文件之一,包含了諸多的重要配置,如IP地址、端口、虛擬主機、context路徑等; tomcat-users.xml: 基于角色實現的認證及授權相關的文件; logging.properties: Tomcat實例的日志相關的定義; web.xml:定義tomcat實例啟動時為所有裝載至當前實例中的webapp定義的默認屬性值;當然,某webapp也可以定義自己的屬性來替代這里的默認值; context.xml: JDBC: (Java Database Connectivity) 基于java的數據庫訪問接口, 即用于讓客戶端訪問數據庫的API; JNDI:(Java Naming and Directory Interface), JAVA的API之一,用于向java語言編寫的應用程序提供命名及目錄的功能; DataSource: 用于通過JDBC API連接關系型數據庫的Java對象,通常需要整合進JNDI并將數據源對象注冊為一個JNDI的名稱服務;這樣對象可以被程序自身訪問,并用于連接至數據庫;一般說來,tomcat7連接至任何數據時通常需要提供以下幾個參數: IP地址 端口號 JNDI名稱 數據庫用戶名及其密碼 DBCP:(Dababase Connection Pool), 其通常位于TOMCAT_HOME或CATALINA_HOME/lib/tomcat-dbcp.jar中,用于實現連接池; Tomcat Manager: tomcat強大的管理工具,具有以下特性: 遠程deploy新應用程序 清理空閑會話 在不重啟container的情況下Undeploy應用程序 分析內存泄漏 JVM狀態 服務器狀態 然而,在tomcat7中,TM默認是禁用的。要啟用之,需要編輯tomcat-users.xml文件; Context: 對于應用程序來說,context路徑是一個關鍵屬性,其也經常用于虛擬主機的配置及.war文件中的URL映射。使用context可以降低系統負載,因為,當某URL請求到達tomcat時,如果沒有context,tomcat需要搜索server.xml或context.xml的配置以確定此URL,否則則需要搜索所有的war文件來查找用戶的請求的資源。 此外,context也可以讓管理員基于每個app提供日志、appBase、DB連接等配置,這極大地增強配置的靈活性; 應用程序目錄的結構: /WEB-INF/web.xml:包含當前webapp的deploy描述符,如所有的servlets和JSP等動態文件的詳細信息,會話超時時間和數據源等;因此,其也通常用于定義當前webapp特有的資源; /WEB-INF/classes: 包含所有服務器端類及當前應用程序相關的其它第三方類等; /WEB-INF/lib: 包含JSP所用到的JAR文件; 用于tomcat的webapp即可以多個獨立的文件組成,也可以是jar打包后的單個文件;這些打包后的文件的擴展名可用于判斷其內容的類型,如: EJB通常打包為.jar webapp通常打包為.war 資源適配器(Resource adapters)通常打包為.rar 企業級應用程序通常打包為.ear,它通常是整合的EJB、webapp及資源適配器文件; Web服務通常會打包為.ear或.war; 于是,到底應該使用展開格式的文件還是打包為單個文件的格式,就需要根據需要進行了。一般說來,如果滿足以下場景,就應該使用展開后的格式,而非打包格式: 1、需要在將來的某個時候更新應用程序中的部分內容;使用展開的格式可以避免重新deploy應用程序; 2、期望使用Tomcat Manager來動態編輯及選擇deployment descriptor值; 3、應用程序中包含靜態文件,而這些靜態文件需要定期更新; Deploy應用程序所涉及到的操作: Deploy: 向tomcat實例提供某應用程序源文件,并讓服務器將類加載進類加器中;這樣,應用程序才可以為用戶所使用; Redeploy:用于更新deployment后的某應用程序或應用程序的部分內容;當redeploy整個應用程序時,當前應用程序的所有模塊都必須要redeploy成功,否則整個webapp將會停止 ; Stop: 卸載當前應用程序的所有類,并停止向用戶提供服務;不過,其仍然會保留所有已deploy的文件及名稱,并可用于后續的redeployment或starting; Start: 重新裝載當前應用的類至類加載器,并開啟服務; Undeploy: 停止某已經deploy的應用程序,并移除deploy產生的文件和名稱; Tomcat7 deploy應用程序的方法: War格式的應用程序:將應用程序war文件放置于CATALINA_BASE目錄中并重新啟動tomcat; 沒打包的應用程序:將應用程序的非歸檔文件旋轉于CATALINA_BASE目錄中; Tomcat Manager:登錄TM而后進行deploy; telnet webserver GET / HTTP/1.1 HOST:localhost Connection:{Keep-Alive|Close} <%@ page language="java" %> <%@ page import="java.util.*" %><% out.println("Hello,world!"); %> # mkdir /usr/local/tcinstance2 # cd /usr/local/tcinstance2 # cp -a $CATALINA_HOME/conf . # mkdir common logs temp server shared webapps work server.xml: # set CATALINA_BASE="/usr/local/tcinstance2" # set CATALINA_HOME="/usr/local/tomcat" # export CATALINA_BASE CATALINA_HOME # service tomcat start # Standard way to start on Linux http://172.16.100.1/manager/html: http://172.16.100.1/manager/text http://172.16.100.1/manager/status 會話管理: 標準會話管理器和持久會話管理器 標準會話管理器(StandardManager): 默認保存于$CATALINA_HOME/work/Catalina/ / /下的SESSIONS.ser文件中。 maxActiveSessions:最多允許的活動會話數量,默認為-1,表示不限制; maxInactiveInterval:非活動的會話超時時長,默認為60s; pathname:會話文件的保存目錄; 持久會話管理器(PersistentManager): 將會話數據保存至持久存儲中,并且能在服務器意外中止后重新啟動時重新加載這些會話信息。持久會話管理器支持將會話保存至文件存儲(FileStore)或JDBC存儲(JDBCStore)中。 保存至文件中的示例: 每個用戶的會話會被保存至directory指定的目錄中的文件中,文件名為 .session,并通過后臺線程每隔一段時間(checkInterval參數定義,默認為60秒)檢查一次超時會話。 保存至JDBCStore中的示例: 安裝apache 6.4.1 安裝apr和apr-util 可以從http://apr.apache.org/獲取apr源碼,目前最新的版本是1.4.6。 [root@www.magedu.com ~]# tar xf apr-1.4.6.tar.bz2 [root@www.magedu.com ~]# cd apr-1.4.6 [root@www.magedu.com ~]# ./configure --prefix=/usr/local/apr --disable-ipv6 [root@www.magedu.com ~]# make && make install apr-util是apr的工具庫,其可以讓程序員更好的使用apr的功能。可以從http://apr.apache.org/獲取apr源碼,目前最新的版本是1.4.1。 [root@www.magedu.com ~]# tar xf apr-util-1.4.1.tar.bz2 [root@www.magedu.com ~]# cd apr-util-1.4.1 [root@www apr-util-1.4.1]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr [root@www apr-util-1.4.1]# make && make install 6.4.2 安裝apache httpd目前最新的2.4系列版本中引入了event MPM,其在性能上較之其它MPM有了較大的提升, [root@www.magedu.com ~]# tar xf httpd-2.4.2 [root@www.magedu.com ~]# cd httpd-2.4.2 [root@www.magedu.com ~]# ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --enable-mpms-shared=all --with-mpm=event --enable-proxy --enable-proxy-http --enable-proxy-ajp --enable-proxy-balancer --enable-lbmethod-heartbeat --enable-heartbeat --enable-slotmem-shm --enable-slotmem-plain --enable-watchdog [root@www.magedu.com ~]# make && make install 為apache提供init腳本,實現服務的控制。建立/etc/rc.d/init.d/httpd文件,并添加如下內容: 這是個腳本文件,因此需要執行權限;同時,為了讓httpd服務能夠開機自動啟動,還需要將其添加至服務列表,并設置其在3或5級別下自動運行。 chmod +x /etc/rc.d/init.d/httpd chkconfig --add httpd chkconfig --level 35 httpd on 6.5 配置apache通過mod_proxy模塊與Tomcat連接 要使用mod_proxy與Tomcat實例連接,需要apache已經裝載mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(實現Tomcat集群時用到)等模塊: # /usr/local/apache/bin/httpd -D DUMP_MODULES | grep proxy proxy_module (shared) proxy_connect_module (shared) proxy_ftp_module (shared) proxy_http_module (shared) proxy_fcgi_module (shared) proxy_scgi_module (shared) proxy_ajp_module (shared) proxy_balancer_module (shared) proxy_express_module (shared) 2、在httpd.conf的全局配置段或虛擬主機中添加如下內容: ProxyVia Off ProxyRequests Off ProxyPreserveHost Off Require all granted ProxyPass / ajp://172.16.100.1:8009/ ProxyPassReverse / ajp://172.16.100.1:8009/Require all granted 或讓apache跟Tomcat的http連接器進行整合: ProxyVia Off ProxyRequests Off ProxyPass / http://172.16.100.1:8080/ ProxyPassReverse / http://172.16.100.1:8080/Require all granted Require all granted 關于如上apache指令的說明: ProxyPreserveHost {On|Off}:如果啟用此功能,代理會將用戶請求報文中的Host:行發送給后端的服務器,而不再使用ProxyPass指定的服務器地址。如果想在反向代理中支持虛擬主機,則需要開啟此項,否則就無需打開此功能。 ProxyVia {On|Off|Full|Block}:用于控制在http首部是否使用Via:,主要用于在多級代理中控制代理請求的流向。默認為Off,即不啟用此功能;On表示每個請求和響應報文均添加Via:;Full表示每個Via:行都會添加當前apache服務器的版本號信息;Block表示每個代理請求報文中的Via:都會被移除。 ProxyRequests {On|Off}:是否開啟apache正向代理的功能;啟用此項時為了代理http協議必須啟用mod_proxy_http模塊。同時,如果為apache設置了ProxyPass,則必須將ProxyRequests設置為Off。 ProxyPass [path] !|url [key=value key=value ...]]:將后端服務器某URL與當前服務器的某虛擬路徑關聯起來作為提供服務的路徑,path為當前服務器上的某虛擬路徑,url為后端服務器上某URL路徑。使用此指令時必須將ProxyRequests的值設置為Off。需要注意的是,如果path以“/”結尾,則對應的url也必須以“/”結尾,反之亦然。 另外,mod_proxy模塊在httpd 2.1的版本之后支持與后端服務器的連接池功能,連接在按需創建在可以保存至連接池中以備進一步使用。連接池大小或其它設定可以通過在ProxyPass中使用key=value的方式定義。常用的key如下所示: ◇ min:連接池的最小容量,此值與實際連接個數無關,僅表示連接池最小要初始化的空間大小。 ◇ max:連接池的最大容量,每個MPM都有自己獨立的容量;都值與MPM本身有關,如Prefork的總是為1,而其它的則取決于ThreadsPerChild指令的值。 ◇ loadfactor:用于負載均衡集群配置中,定義對應后端服務器的權重,取值范圍為1-100。 ◇ retry:當apache將請求發送至后端服務器得到錯誤響應時等待多長時間以后再重試。單位是秒鐘。 如果Proxy指定是以balancer://開頭,即用于負載均衡集群時,其還可以接受一些特殊的參數,如下所示: ◇lbmethod:apache實現負載均衡的調度方法,默認是byrequests,即基于權重將統計請求個數進行調度,bytraffic則執行基于權重的流量計數調度,bybusyness通過考量每個后端服務器的當前負載進行調度。 ◇ maxattempts:放棄請求之前實現故障轉移的次數,默認為1,其最大值不應該大于總的節點數。 ◇ nofailover:取值為On或Off,設置為On時表示后端服務器故障時,用戶的session將損壞;因此,在后端服務器不支持session復制時可將其設置為On。 ◇ stickysession:調度器的sticky session的名字,根據web程序語言的不同,其值為JSESSIONID或PHPSESSIONID。 上述指令除了能在banlancer://或ProxyPass中設定之外,也可使用ProxySet指令直接進行設置,如:BalancerMember http://www1.magedu.com:8080 loadfactor=1 BalancerMember http://www2.magedu.com:8080 loadfactor=2 ProxySet lbmethod=bytraffic ProxyPassReverse:用于讓apache調整HTTP重定向響應報文中的Location、Content-Location及URI標簽所對應的URL,在反向代理環境中必須使用此指令避免重定向報文繞過proxy服務器。 6.6 配置apache通過mod_jk模塊與Tomcat連接 mod_jk是ASF的一個項目,是一個工作于apache端基于AJP協議與Tomcat通信的連接器,它是apache的一個模塊,是AJP協議的客戶端(服務端是Tomcat的AJP連接器)。 [root@www.magedu.com ~]# tar xf tomcat-connectors-1.2.37-src.tar.gz [root@www.magedu.com ~]# cd tomcat-connectors-1.2.37-src/native/ [root@www.magedu.com ~]# ./configure --with-apxs=/usr/local/apache/bin/apxs [root@www.magedu.com ~]# make && make install apache要使用mod_jk連接器,需要在啟動時加載此連接器模塊。為了便于管理與mod_jk模塊相關的配置,這里使用一個專門的配置文件/etc/httpd/extra/httpd-jk.conf來保存相關指令及其設置。其內容如下: # Load the mod_jk LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/extra/workers.properties JkLogFile logs/mod_jk.log JkLogLevel debug JkMount /* TomcatA JkMount /status/ stat1 除了需要使用LoadModule指令在apache中裝載模塊外,mod_jk還需要在apache的主配置文件中設置其它一些指令來配置其工作屬性。如JkWorkersFile則用于指定保存了worker相關工作屬性定義的配置文件,JkLogFile則用于指定mod_jk模塊的日志文件,JkLogLevel則可用于指定日志的級別(info, error, debug),此外還可以使用JkRequestLogFormat自定義日志信息格式。而JkMount(格式: JkMount)指定則用于控制URL與Tomcat workers的對應關系。 為了讓apache能使用/etc/httpd/extra/httpd-jk.conf配置文件中的配置信息,需要編輯/etc/httpd/httpd.conf,添加如下一行: Include /etc/httpd/extra/httpd-jk.conf 對于apache代理來說,每一個后端的Tomcat實例中的engine都可以視作一個worker,而每一個worker的地址、連接器的端口等信息都需要在apache端指定以便apache可以識別并使用這些worker。約定俗成,配置這些信息的文件通常為workers.properties,其具體路徑則是使用前面介紹過的JkWorkersFile指定的,在apache啟動時,mod_jk會掃描此文件獲取每一個worker的配置信息。比如,我們這里使用/etc/httpd/extra/workers.properties。 workers.properties文件一般由兩類指令組成:一是mod_jk可以連接的各worker名稱列表,二是每一個worker的屬性配置信息。它們分別遵循如下使用語法。 worker.list = < a comma separated list of worker names > worker. . = 其中worker.list指令可以重復指定多次,而worker name則是Tomcat中engine組件jvmRoute參數的值。如: worker.TomcatA.host=172.16.100.1 根據其工作機制的不同,worker有多種不同的類型,這是需要為每個worker定義的一項屬性woker. .type。常見的類型如下: ◇ ajp13:此類型表示當前worker為一個運行著的Tomcat實例。 ◇ lb:lb即load balancing,專用于負載均衡場景中的woker;此worker并不真正負責處理用戶請求,而是將用戶請求調度給其它類型為ajp13的worker。 ◇ status:用戶顯示分布式環境中各實際worker工作狀態的特殊worker,它不處理任何請求,也不關聯到任何實際工作的worker實例。具體示例如請參見后文中的配置。 worker其它常見的屬性說明: ◇ host:Tomcat 7的worker實例所在的主機; ◇ port:Tomcat 7實例上AJP1.3連接器的端口; ◇ connection_pool_minsize:最少要保存在連接池中的連接的個數;默認為pool_size/2; ◇ connection_pool_timeout:連接池中連接的超時時長; ◇ mount:由當前worker提供的context路徑,如果有多個則使用空格格開;此屬性可以由JkMount指令替代; ◇ retries:錯誤發生時的重試次數; ◇ socket_timeout:mod_jk等待worker響應的時長,默認為0,即無限等待; ◇ socket_keepalive:是否啟用keep alive的功能,1表示啟用,0表示禁用; ◇ lbfactor:worker的權重,可以在負載均衡的應用場景中為worker定義此屬性; 另外,在負載均衡模式中,專用的屬性還有: ◇balance_workers:用于負載均衡模式中的各worker的名稱列表,需要注意的是,出現在此處的worker名稱一定不能在任何worker.list屬性列表中定義過,并且worker.list屬性中定義的worker名字必須包含負載均衡worker。具體示例請參見后文中的定義。 ◇ method:可以設定為R、T或B;默認為R,即根據請求的個數進行調度;T表示根據已經發送給worker的實際流量大小進行調度;B表示根據實際負載情況進行調度。 ◇sticky_session:在將某請求調度至某worker后,源于此址的所有后續請求都將直接調度至此worker,實現將用戶session與某worker綁定。默認為值為1,即啟用此功能。如果后端的各worker之間支持session復制,則可以將此屬性值設為0。 根據前文中的指定,這里使用/etc/httpd/extra/workers.properties來定義一個名為TomcatA的worker,并為其指定幾個屬性。文件內容如下: worker.list=TomcatA,stat1 worker.TomcatA.port=8009 worker.TomcatA.host=172.16.100.1 worker.TomcatA.type=ajp13 worker.TomcatA.lbfactor=1 worker.stat1.type = status 至此,一個基于mod_jk模塊與后端名為TomcatA的worker通信的配置已經完成,重啟httpd服務即可生效。 配置基于mod_jk的負載均衡 1、 為了避免用戶直接訪問后端Tomcat實例,影響負載均衡的效果,建議在Tomcat 7的各實例上禁用HTTP/1.1連接器。 2、為每一個Tomcat 7實例的引擎添加jvmRoute參數,并通過其為當前引擎設置全局惟一標識符。如下所示。需要注意的是,每一個實例的jvmRoute的值均不能相同。 而后去配置apache,修改/etc/httpd/extra/httpd-jk.conf為如下內容: LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/extra/workers.properties JkLogFile logs/mod_jk.log JkLogLevel debug JkMount /* lbcluster1 JkMount /jkstatus/ stat1 編輯/etc/httpd/extra/workers.properties,添加如下內容: worker.list = lbcluster1,stat1 worker.TomcatA.type = ajp13 worker.TomcatA.host = 172.16.100.1 worker.TomcatA.port = 8009 worker.TomcatA.lbfactor = 5 worker.TomcatB.type = ajp13 worker.TomcatB.host = 172.16.100.2 worker.TomcatB.port = 8009 worker.TomcatB.lbfactor = 5 worker.lbcluster1.type = lb worker.lbcluster1.sticky_session = 1 worker.lbcluster1.balance_workers = TomcatA, TomcatB worker.stat1.type = status 演示效果,在TomcatA上某context中(如/test),提供如下頁面 <%@ page language="java" %> TomcatA
<% session.setAttribute("abc","abc"); %>
Session ID <%= session.getId() %>