Tomcat

Tomcat

JVM的核心組成部分:html

  • Class Loder
  • 執行引擎

Java編程語言特性:面向對象,多線程,結構化錯誤處理,垃圾收集,動態連接,動態擴展前端

堆:建立的對象都在堆內存中 GC:垃圾收集器,主要收集堆內存中的對象java

JDK:java開發工具箱,提供了JAVA的類庫,開發工具和apinode

JRE:java運行時環境(java runtime environment),運行java代碼,不能開發java代碼mysql

JRE(java runtime environment):包含了JVM和其餘一些簡單功能的JAVA運行環境,適用於只運行java程序時。nginx

JDK(java DevelopmentKit)比JRE包含了更多東西,除了能做爲JAVA運行環境,還提供了不少用於開發的工具適用於開發程序時使用web

JAVA SE是java開發標準版,裏面有JDK,Java EE是企業版,本質上ee只是比se多提供了幾個類庫而已。算法

JVM運行時區域:運行爲多個線程sql

  • 方法區:線程共享,用於存儲被虛擬機加載的類信息、常量、靜態變量等 持久代
  • 堆:jvm所管理的內存中最大的一部分,也是GC管理的主要區域,主流的算法都基於分代收集方式進行,新生代和老年代,貢獻內存區;
  • Java棧:線程私有,存儲線程本身的局部變量等信息
  • PC寄存器:(program count register),線程獨佔的內存空間
  • 本地方法棧:依賴於平臺

Web Container:

  • 商業實現:
    1. WebSphere(IBM)
    2. WebLogic(Oracle)
    3. Oc4j
    4. Glassfish
    5. JBoss
  • 開源實現:
    1. Tomcat
    2. Jetty
    3. Resin

運行過程圖解

  • jsp --> jasper--> servlet --> complie --> bytecodes --> jvm

Tomcat核心組件

catalina:servlet container

Coyote:http connection

Jasper: JSP Engine

Tomcat 開發語言: Java

Tomcat instance : 運行中的tomcat進程(java進程)

  • server:即一個tomcat實例
  • Engine:Tomcat的核心組件,用於運行jsp或servlet代碼
  • Connector: 接收並解析用戶請求,將請求映射爲Engine中運行的代碼,以後將運行結果構建成響應報文
  • service:用於把connector組件和engine組件關聯起來,一個service只能包含一個engine組件和一個或多個connector
  • host:相似於httpd中的虛擬主機
  • Context:相似於httpd中的alias

注意:每一個組件都由類來實現,有些組件的實現還不止一種

頂級類組件:server

服務類組件:service

容器類組件:engine,host,context

鏈接器組件:connector

被嵌套類組件:valve, logger,realm

Tomcat運行模式

  • standalone:經過內置的Web Server(http connector)來接收客戶端的請求
  • proxy:由專門的web server服務客戶端的http請求
    1. in-process : 部署於同一主機
    2. network: 部署於不一樣主機

安裝Tomcat

官方站點

  • 安裝JDK,配置環境變量

    [root@localhost ~]# cat /etc/profile.d/jdk.sh 
    export JAVA_HOME=/usr/java/latest
    export PATH=$JAVA_HOME/bin:$PATH
  • 安裝Tomcat配置環境變量

    [root@localhost ~]# cat /etc/profile.d/tomcat.sh 
    export CATALINA_HOME=/usr/local/tomcat
    export PATH=$CATALINA_HOME/bin:$PATH

Tomcat目錄結構:

  • bin:腳本及啓動時用到的類
  • lib:類庫
  • conf:配置文件
  • logs:日誌文件
  • webapps:應用程序默認部署目錄
  • work:工做目錄
  • temp:臨時文件目錄

配置文件

  • server.xml:主配置文件
  • context.xml: 每一個webapp均可以有專用的配置文件,這些配置文件一般位於webapp應用程序目錄下的WEB-INF目錄中,用於定義會話管理器、JDBC等,conf/context.xml是爲各webapp提供默認配置的
  • web.xml:每一個webapp部署以後才能被訪問,此文件則用於爲全部的webapp提供默認部署相關配置
  • tomcat-users.xml:用戶認證的帳號和密碼配置文件
  • catalina.policy:當使用-security選項啓動tomcat實例時會讀取此配置文件來實現其安全運行策略
  • catalina.properties:Java屬性的定義文件,用於設定類加載器路徑等,一級一些JVM性能相關的調優參數
  • logging.properties:日誌相關的配置信息

WEB-INF/:當前webapp的私有資源目錄,一般存放當前webapp自用的web.xml

META-INF/:當前webapp的私有資源目錄,一般存放當前webapp自用的context.xml

classes/:此webapp的私有類

lib/: 此webapp的私有類,被打包爲jar格式類

index.jsp:webapp的主頁

webapp歸檔格式:

  • .war:webapp
  • .jar:EJB的類
  • .rar:資源適配器
  • .ear:企業級應用程序

Tomcat配置文件結構

<server>
    <service>
        <connector port="8080"/>   #http協議默認端口
        <connector port="8009" protocol="AJP/1.3"/>   #ajp協議默認端口
        <engine>
            <Host>
            </Host>
                <Context />
        </engine>
    </service>
</server>

手動添加一個測試應用程序:

  • 建立特定目錄結構

    mkdir -p myapp/{lib, classes. WEB-INF, MEAT-INF}
  • 測試文件

    [root@localhost myapp]# cat index.jsp 
    <%@ page language="java" %>
    <%@ page import="java.util.*" %>
    <html>
    <head>
    <title> JSP test page </title>
    </head>
    <body>
    <% out.println("hello world"); %>
    </body>
    </html>

示例配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" enableLookups="false" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
   <Engine name="Catalina" defaultHost="localhost">
     <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase" />
      </Realm>

<!--  今後處開始添加如下兩個Host容器做爲虛擬主機 -->
<!-- 定義一個在$CATALINA_HOME以外的虛擬主機 -->
      <Host name="www.longshuai.com"  appBase="/www/longshuai"
            unpackWARs="true" autoDeploy="true">
          <Context path="" docBase="/www/longshuai" reloadable="true" />
          <Context path="/xuexi" docBase="xuexi" reloadable="true" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="longshuai_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
<!-- 定義一個在$CATALINA_HOME/webapps下的虛擬主機 -->
      <Host name="www.xiaofang.com"  appBase="webapps/xiaofang"
            unpackWARs="true" autoDeploy="true">
          <Context path="" docBase="" reloadable="true" />
          <Context path="/xuexi" docBase="xuexi" reloadable="true" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="xiaofang_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
<!-- 默認虛擬主機localhost,可不修改 -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

除了engine中定義的默認localhost虛擬主機,另外佈置了兩個虛擬主機www.longshuai.com和www.xiaofang.com,它們的程序目錄分別爲/www/longshuai和$CATALINA_HOME/webapps/xiaofang,因此須要提早創建好這兩個目錄。另外,在context中定義了docBase,對於uri路徑/xuexi,它的文件系統路徑分別爲/www/longshuai/xuexi目錄和$CATALINA_HOME/webapps/xiaofang/xuexi,因此也要在上面兩個程序目錄中定義好xuexi目錄。除此以外,還分別爲這3個虛擬主機定義了日誌,它們的路徑爲相對路徑logs,相對於$CATALINA_HOME。

再提供appBase目錄和docBase目錄。

mkdir -p /www/longshuai/xuexi
mkdir -p /usr/local/tomcat/webapps/xiaofang/xuexi

再提供測試用的index.jsp文件。內容大體以下,分別複製到如下四個目錄中:
/www/longshuai/
/www/longshuai/xuexi/
/usr/local/tomcat/webapps/xiaofang/
/usr/local/tomcat/webapps/xiaofang/xuexi

並將out.println的輸出內容分別稍做修改,使可以區分讀取的是哪一個index.jsp。

<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
  <body>
    <% out.println("hello world from longshuai Root"); %>
  </body>
</html>

配置解析

定義鏈接器時能夠配置的屬性很是多,但一般定義HTTP鏈接器時必須定義的屬性只有「port」,定義AJP鏈接器時必須定義的屬性只有「protocol」,由於默認的協議爲HTTP。如下爲經常使用屬性的說明:

  • address:指定鏈接器監聽的地址,默認爲 0.0.0.0
  • maxThreads:支持的最大併發鏈接數,默認爲200
  • port:監聽的端口,默認爲0
  • protocol:鏈接器使用的協議,默認爲HTTP/1.1,定義AJP協議時一般使用AJP/1.3
  • redirectPort:若是某鏈接器支持的協議是HTTP,當接收客戶端發來的HTTPS請求時,則轉發至此屬性定義的端口
  • connectionTimeout:等待客戶端發送請求的超時時間,單位爲毫秒。默認爲60000,即一分鐘
  • enableLookups:是否經過request.getRemoteHost()進行DNS查詢以獲取客戶端的主機名,默認爲True
  • acceptCount:設置等待隊列的最大長度,一般在tomcat全部處理線程均處於繁忙狀態時,新發來的請求將放置在等待隊列中

下面定義了一個多個屬性的SSL鏈接器:

<Connector port="8443"
           maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
           enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS" />

Host組件

位於Engine容器中用於接收請求並進行相應處理的主機或虛擬主機

<Host name="localhost" appBase="webapps"
      unpackWARs="true" autoDeploy="true"
      xmlValidation="false" xmlNamespaceAware="false">
</Host>

經常使用屬性說明

  • appBase:此Host的webapps目錄,即存放非歸檔的web應用程序目錄或歸檔後的WAR文件的目錄路徑,可使用基於$CATALINA_HOME的相對路徑
  • autoDeploy:在Tomcat處於運行狀態時放置於appBase目錄中的應用程序文件是否自動進行deploy:默認爲true
  • unpackWars:在啓用此webapps時是否對WAR格式的歸檔文件先進行展開:默認爲true

虛擬主機定義示例:

<Engine name="Catalina" defaultHost="localhost">
    <Host name="localhost" appBase="webapps">
        <context path="" docBase="ROOT"/>
        <context path="/bbs" docBase="/web/bbs"
                 reloadable="true" crossContext="true"/>
    </Host>
    <Host name="www.template.com" appBase="/web/tem">
        <context path="/" docBase="ROOT"/>
    </Host>
</Engine>

主機別名定義:

若是一個主機有兩個或兩個以上的主機名:額外的名稱都可以以別名的形式進行定義,以下:

<Host name="www.template.com" appBase="webapps" unpackWARs="true">
    <alias>template.com</alias>  
</Host>

撇開tomcat做爲servlet容器的行爲。它和apache、nginx的功能大體都能對應上。例如以nginx爲例,如下是nginx提供web服務時的配置結構:

server {
    listen PORT;
    server_name www.a.com;   # 對應於<host name=www.a.com>
    location / {             # 對應於context path=""
            root   html;     # 對應於docBase
        }
    location /xuexi {        # 對應於context path="/xuexi"
            root   html/xuexi;
        }
}

Tomcat中的appBase和docBase詳細說明

這兩貨雖然意義很明確,但"潛規則"很嚴重。如下面的配置爲例。

<host name=www.a.com appBase=/www/a >
    <context path="" docBase=/www/a />
    <context path="/xuexi" docBase=/www/a/xuexi />
</host>

appBase是虛擬主機存放webapp的目錄,它能夠是相對路徑,也能夠是絕對路徑。若是是相對路徑,則相對於$CATALINA_HOME,嚴格並準確地說是$CATALINA_BASE。

path是URI的匹配路徑,至關於nginx的location後的路徑。tomcat要求每一個虛擬主機必須配置一個空字符串的path,該條context做爲URI沒法被明確匹配時的默認context,它至關於nginx中location / {}的做用。

docBase則是每一個webapp的存放目錄(或者是已歸檔的war文件),它能夠是相對路徑,也能夠是絕對路徑,提供相對路徑時它相對於appBase。該目錄通常在appBase的目錄下,但並不規定必定要放在appBase下。對於web服務來講,它至關於nginx的root指令,但對於webapp來講,一個context就至關於一個webapp,而docBase正是webapp的路徑。

"潛規則"在於默認的context如何提供。有如下幾種狀況:

  1. 明肯定義了<context path="" docBase=webappPATH>,此時默認context的處理路徑爲webappPATH。
  2. 明肯定義了<context path="">,但卻沒給定docBase屬性,此時該默認context處理路徑爲appBase/ROOT目錄,注意ROOT爲大寫。
  3. 徹底沒有定義path=""的context時,即host容器中沒有明確的path="",此時將隱式定義一個默認context,處理路徑爲appBase/ROOT目錄。
  4. 定義了path但沒有定義docBase屬性時,docBase將根據path推斷出它的路徑。推斷的規則以下:(注:此時推斷的不是默認context,而是對應context的docbase)
context path    context name    推斷出的docBase路徑
--------------------------------------------------
/foo            /foo            foo    
/foo/bar        /foo/bar        foo/bar
Empty String    Empty String    ROOT

顯然,沒有給定path=""或缺乏docbase時,都以ROOT做爲目錄。如下是幾個定義示例:

# 虛擬主機中沒有定義任何context,將以appBase下的ROOT做爲默認處理路徑
<Host appBase="webapps">
</Host>

# 沒有定義path=""的context,但定義了path非空的context,也將以ROOT做爲默認處理路徑
# 若是下面的Context容器中省略docBase屬性,則推斷出該context的docBase路徑爲appBase/xuexi
<Host appBase="webapps">
    <Context path="/xuexi" docBase="webappPATH" />
</Host>

# 某個context定義了path="",該context將做爲默認context
# 但該默認context若是沒有定義docBase,將推斷出其docBase路徑爲appBase/ROOT
<Host appBase="webapps">
    <Context path="" docBase="webappPATH" />
</Host>

# 某個context定義了path="",該context將做爲默認context
# 下面的默認context明肯定義了docBase
<Host appBase="webapps">
    <Context path="" docBase="webappPATH" />
</Host>

舉個直觀的例子,若是某個Host配置以下。

<Host name="www.xiaofang.com" appBase="/www/xiaofang" unpackWARs="true" autoDeploy="true">
    <Context path="/xuexi" docBase="xuexi" reloadable="true" />
</Host>

那麼瀏覽器訪問http://www.xiaofang.com:8080/xuexi/將請求/www/xiaofang/xuexi/index.jsp

因爲沒有定義path=""的Context組件,所以瀏覽器訪問http://www.xiaofang.com:8080將請求/www/xiaofang/ROOT/index.jsp。注意,是ROOT目錄。

若是加上<Context path="" docBase="" reloadable="true" />,則訪問http://www.xiaofang.com:8080將請求/www/xiaofang/index.jsp。注意,不是ROOT目錄,而是相對於appBase的根目錄,即/www/xiaofang。

儘管本文解釋了一大堆關於appBase和docBase的設置,但通常都會採用大衆所熟知的配置方式:appBase設置爲"webapps",即$CATALINA_HOME/webapps,而docBase設置爲webapps下的webapp應用名。這樣配置不只符合eclipse部署webapp時默認的部署目錄結構(eclipse部署應用時,將WebContent下的內容複製到docBase下,將servlet java源代碼編譯後的class文件複製到WEB-INF/classes目錄下),更利於維護webapp和相關配置。例如:

<Context docBase="MyWeb" path="/MyWeb" reloadable="true" />
<Context docBase="SecondWeb" path="/SecondWeb" reloadable="true" />
<Context docBase="WEB" path="/WEB" reloadable="true" />

但這樣的配置有個缺點,由於項目名稱通常都會帶有大寫字母,使得在瀏覽器訪問時,也要帶有大寫字母。例如輸入http://www.a.com/MyWeb/index.jsp。所以,可採用另外一種配置方式:設置Host的appBase爲webapps下的某個目錄,而後在path上配置uri匹配路徑。以下:

<Host name="www.xiaofang.com" appBase="webapps/MyWeb" unpackWARs="true" autoDeploy="true">
    <Context path="/xuexi" docBase="xuexi" reloadable="true" />
    <Context path="" docBase="" reloadable="true" />
</Host>

注意:path不能以「/」結尾

被嵌套的valve

Valve中文意思是閥門,相似於過濾器,它能夠工做於Engine和Host/Context之間、Host和Context之間以及Context和Web應用程序的某資源之間。一個容器內能夠創建多個Valve,並且Valve定義的次序也決定了它們生效的次序。

有多種不一樣的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:

<Context privileged="true" path="/probe" docBase="probe">
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
  allow="127\.0\.0\.1"/>
</Context>

其中相關屬性定義有:

  • className:在對應位置的後綴上加上".valves.RemoteHostValve"或".valves.RemoteAddrValve";
  • allow:以逗號分開的容許訪問的IP地址列表,支持正則,點號「.」用於IP地址時須要轉義;僅定義allow項時,非明確allow的地址均被deny;
  • deny: 以逗號分開的禁止訪問的IP地址列表,支持正則;使用方式同allow;僅定義deny項時,非明確deny的地址均被allow;

另一個經常使用的Valve爲AccessLogValve,定義方式大體以下:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

其中prefix和suffix表示日誌文件的前綴名稱和後綴名稱。pattern表示記錄日誌時的信息和格式。


LNMT

流程:

client --> nginx --> reverse_proxy --> http --> tomcat (http connector)

location ~* \.(jsp|do)$ {
        proxy_pass http://www.template.com:8080;
}

LAMT

client --> http --> httpd --> reverse_proxy --> (http|ajp) --> tomcat(http connector |ajp connector)

反代模塊:

​ 主:proxy_module

​ 子:proxy_module_http, proxy_module_ajp

​ 第三方模塊:jk

​ ajp協議

httpd要擴展模塊須要藉助apxs,它是httpd的開發包httpd-devel中工具,因此先要安裝httpd-devel。若是是編譯安裝的httpd,則devel包已經裝好,若是是yum安裝,則須要額外安裝httpd-devel包。

yum -y install httpd httpd-devel

httpd虛擬主機反向代理

基於proxy_module_http

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass / http://192.168.175.3:8080/
    ProxyPassReverse / http://192.168.175.3:8080/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

基於proxy_module_ajp

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass / ajp://192.168.175.3:8009/
    ProxyPassReverse / ajp://192.168.175.3:8009/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

若是不想把status頁面反代至後端服務器能夠加上 ProxyPass /status !

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass /status !
    ProxyPass / ajp://192.168.175.3:8009/
    ProxyPassReverse / ajp://192.168.175.3:8009/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

apache指令說明:

  • ProxyPreserveHost {on|off}:若是啓用此功能,代理會將用戶請求報文中的Host:行發送給後端的服務器,而再也不使用ProxyPass指定的服務器地址。若是想在反向代理中支持虛擬主機,則須要開啓此項,不然就無需打開此功能
  • ProxyVia {on|off|Full|Block}:用於控制在http首部是否使用Via,主要用於在多級代理中控制代理請求的流向。默認爲off,即不啓用此功能,on表示每一個請求和響應報文均添加Via,Full表示每一個Via行都會添加當前apache的版本號信息,Block表示每一個代理請求報文中的Via都會被移除
  • ProxyRequest {on|off}:是否開啓apache正向代理的功能,啓用此項時爲了代理http協議必須啓用mod_proxy_http模塊,同時,若是爲apache設置了ProxyPass,則必須將ProxyRequests設置爲off
  • ProxyPass [path] ! | url [key=value key=value….] : 將後端服務器某URL與當前服務器的某虛擬路徑關聯起來做爲提供服務的路徑,若是path以「/」結尾,則對應的url也必須以「/」結尾
    • min:鏈接池的最小容量
    • max:鏈接池的最大容量
    • 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

    上述指令除了能在balancer://或ProxyPass中設定以外,也可使用ProxySet指令直接進行設置,如:

    <Proxy balancer://hotcluster>
        BalancerMember http://www1.template.com:8080 loadfactor=1
        BalancerMember http://www2.template.com:8080 loadfactor=2
        ProxySet lbmethod=bytraffic
    </Proxy>
  • ProxyPassReverse:用於讓apache調整HTTP重定向響應報文中的Location、Content-Location及URI標籤所對應的URL,在反向代理環境中必須使用此指令避免重定向繞過proxy服務器

基於mod_proxy實現負載均衡

在http.conf全局配置文件中配置以下內容:

ProxyRequests off
<Proxy balancer://lbcluster1>
    BalancerMember ajp://172.16.100.1:8009 loadfactor=10 route=TomcatA
    BalancerMember ajp://172.16.100.2:8009 loadfactor=10 route=TomcatB
</Proxy>

<VirtualHost *:80>
    ServerAdmin admin@163.com
    ServerName www.template.com
    ProxyPass / balancer://lbcluster1/
    ProxyPassReverse / balancer://lbcluster1/
</VirtualHost>

<Proxy balancer://hotcluster>
    BalancerMember http://www1.template.com:8080 loadfactor=1
    BalancerMember http://www2.template.com:8080 loadfactor=2 
    ProxySet lbmethod=bytraffic
</Proxy>
<Proxy balancer://lbcluster1>
   BalancerMember http://192.168.175.4:8080 loadfactor=10 route=TomcatA
   BalancerMember http://192.168.175.5:8080 loadfactor=10 route=TomcatB
</Proxy>

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass / balancer://lbcluster1/
    ProxyPassReverse / balancer://lbcluster1/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

若是須要會話綁定,可像以下配置:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://lbcluster1>
   BalancerMember http://192.168.175.4:8080 loadfactor=10 route=TomcatA
   BalancerMember http://192.168.175.5:8080 loadfactor=10 route=TomcatB
   ProxySet stickysession=ROUTEID
</Proxy>

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass / balancer://lbcluster1/
    ProxyPassReverse / balancer://lbcluster1/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

基於ajp實現負載均衡:

#Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://lbcluster1>
   BalancerMember ajp://192.168.175.4:8009 loadfactor=10 route=TomcatA
   BalancerMember ajp://192.168.175.5:8009 loadfactor=10 route=TomcatB
   ProxySet stickysession=ROUTEID
</Proxy>

<VirtualHost *:80>
  ServerName www.template.com
  ProxyVia On
  ProxyRequests Off
  ProxyPreserveHost On
  <Proxy *>
    Require all granted
  </Proxy>
    ProxyPass / balancer://lbcluster1/
    ProxyPassReverse / balancer://lbcluster1/
  <Location />
    Require all granted
  </Location>
</VirtualHost>

配置apache經過mod_jk模塊與tomcat鏈接

mod_jk是ASF的一項目,是一工做於apache端基於AJP協議與tomcat通訊的鏈接器,它是apache的一個模塊,是AJP協議的客戶端(服務端是Tomcat的AJP鏈接器)

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/worker.properties
JkLogFile logs/mod_jk.log
JkLogLevel debug
JkMount /* TomcatA
JkMount /status stat1

當前最新穩定版的mod_jk是1.2.42版本。

mod_jk下載地址:http://tomcat.apache.org/download-connectors.cgi
mod_jk官方手冊:http://tomcat.apache.org/connectors-doc/

httpd要擴展模塊須要藉助apxs,它是httpd的開發包httpd-devel中工具,因此先要安裝httpd-devel。若是是編譯安裝的httpd,則devel包已經裝好,若是是yum安裝,則須要額外安裝httpd-devel包。

此處爲了方便,httpd使用yum安裝。因此編譯mod_jk的方式以下:

yum -y install httpd httpd-devel
tar xf tomcat-connectors-1.2.42-src.tar.gz
cd tomcat-connectors-1.2.42-src/native/
./configure --with-apxs=/usr/bin/apxs --prefix=/usr/local/tomcat/mod_jk
make && make install

此處暫先配置httpd與其中一個tomcat(192.168.100.22)鏈接。後文在說明負載均衡時再引入另外一個tomcat。

先提供一個額外的httpd配置文件。

[root@xuexi ~]# cat /etc/httpd/conf.d/mod_jk.conf
LoadModule  jk_module  modules/mod_jk.so
JkWorkersFile  /etc/httpd/conf.d/workers.properties
JkLogFile  logs/mod_jk.log
JkLogLevel  debug
######### "JkMount /* TomcatA" will send all request to TomcatA   ########
JkMount   /*.jsp        TomcatA
JkMount   /status/*     statA
JkUnMount /images/*     TomcatA
JkUnMount /css/*.*      TomcatA
JkUnMount /css_js/*     TomcatA
JkUnMount /*.html       TomcatA
JkUnMount /*.js         TomcatA

mod_jk的配置文件官方手冊:http://tomcat.apache.org/connectors-doc/reference/apache.html。如下是幾個經常使用的指令說明

  • LoadModule指令用於裝載mod_jk相關模塊,除此以外還須要在httpd的配置文件中設置其它一些指令來配置其工做屬性。如:
  • JkWorkersFile用於指定保存了worker相關工做屬性定義(見下文)的配置文件。
  • JkLogFile用於指定mod_jk模塊的日誌文件。
  • JkLogLevel用於指定日誌級別(info,error,debug),此外還可使用JkRequestLogFormat自定義日誌信息格式。
  • JkMount(格式:JkMount )則用於控制URL與Tomcat workers的對應關係。能夠理解爲轉發請求的意思,例如"/status/*"表示url地址後加上/status/可轉發至statA這個worker上。注意,JkMount匹配的URL是相對的。若是JkMount指令放在Location指令中,如<Location /app>,則JkMount將從/app的後面開始匹配。

JkMount和JkUnMount是很重要的指令,mod_jk性能之因此比mod_proxy好,就是由於經過這兩個指令能夠實現動靜分離,使得只將動態請求轉發給tomcat。其中JkMount指定要轉發給tomcat處理的請求,JkUnMount指定明確不轉發給tomcat而是在本地處理的請求。雖然不指定JkUnMount時,也表示不轉發給tomcat,但若是有重疊時,則應該指定JkUnMount。例以下面的例子,除了/myapp/下的js文件,其餘都轉發給tomcat1處理。

JkMount /myapp/* tomcat1
JkUnMount /myapp/*.js tomcat1

對於apache來講,每個後端Tomcat實例中的engine均可以視做一個worker,而每個worker的地址、Connector的端口等信息都須要在apache端指定以即可以識別並使用這些worker。配置這些信息的文件一般爲"workers.properties",其具體路徑是使用前面介紹過的JkWorkersFile指定的。在apache啓動時,mod_jk會掃描此文件獲取每個worker配置信息。如這裏使用/etc/httpd/conf.d/workers.properties

workers.properties文件通常由兩類指令組成:一是mod_jk能夠鏈接的各worker名稱列表,二是每個worker的屬性配置信息。詳細的配置方法見官方手冊:http://tomcat.apache.org/connectors-doc/reference/workers.html

如下是和上述/etc/httpd/conf.d/mod_jk.conf中配置相對應的/etc/httpd/conf.d/workers.properties。

[root@xuexi tomcat]# cat /etc/httpd/conf.d/workers.properties
worker.list=TomcatA,statA
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.100.22
worker.TomcatA.port=8009
worker.TomcatA.lbfactor=1
worker.statA.type = status

關於worker的配置,它們分別遵循以下使用語法。

worker.list = <a comma separated list of worker_name>
worker.<worker_name>.<property>=<property value>

其中worker.list指令能夠重複指定屢次。worker_name是Tomcat中engine組件中jvmRoute屬性的值(jvmRoute能夠不指定,此時worker_name僅用於標識worker)。

根據工做機制的不一樣,worker有多種不一樣的類型,每一個worker都須要指定其類型,即設定woker..type項。常見的類型以下:其中ajp13是默認值。

  • ajp13:此類型是web server和tomcat首選的類型。此外,還有ajp12和ajp14,但它們一個廢棄一個處於測試階段。
  • lb:lb用於負載均衡場景中的worker;此worker並不真正負責處理用戶請求,而是將用戶請求調度給其它類型爲ajp13的worker。
  • status:用戶顯示負載均衡中各worker工做狀態的特殊worker,它不處理任何請求,也不關聯到任何實際工做的tomcat實例。

因爲status是狀態監控頁面,因此應該保證其安全性,能夠在httpd的配置文件中加入如下控制列表:

# 注意,必須加上尾隨斜線,由於在mod_jk.conf中已經明確了"/status/*"
# For http 2.2
<Location /status/>
    Order deny,allow
    Deny from all
    Allow from 192.168.100.0/24
</Location>

# For http 2.4
<Location /status/>
    Requrie ip 192.168.100
</Location>

除了type屬性外,worker其它常見的屬性有:

除了type屬性外,worker其它常見的屬性有:

  • host:worker所在的主機,更具體的是tomcat上connector組件設置的ajp監聽地址;
  • port:worker的AJP1.3鏈接器監聽的端口;
  • connection_pool_minsize:最少要保存在鏈接池中的鏈接的個數;默認爲pool_size/2;
  • connection_pool_timeout:鏈接池中鏈接的超時時長;
  • mount:由當前worker提供的context路徑,若是有多個則使用空格格開;可考慮在httpd端使用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,即根據請求的個數進行調度(wrr);T表示根據已經發送給worker的實際流量大小進行調度;B表示根據實際負載狀況進行調度(leastconn)。
  • sticky_session:將某請求調度至某worker後,此地址後續全部請求都將直接調度至此worker,實現將用戶session與某worker綁定。默認爲值爲true,即啓用此功能。若是後端的各worker之間支持session複製,則可設爲false。

至此,一個基於mod_jk模塊與後端名爲TomcatA的worker通訊的配置已經完成,重啓httpd服務便可生效。

經過mod_jk負載均衡tomcat

使用mod_jk實現tomcat的負載均衡有一個好處,tomcat上能夠禁用http協議(將監聽此協議的Connector配置刪除便可),防止外界直接經過http請求tomcat。

配置apache,使其支持負載均衡,修改/etc/httpd/conf.d/mod_jk.conf爲以下內容:

LoadModule      jk_module  modules/mod_jk.so
JkWorkersFile   /etc/httpd/conf.d/workers.properties
JkLogFile       logs/mod_jk.log
JkLogLevel      notice
JkMount         /*.jsp     TomcatLB
JkMount         /status/*  statA

編輯/etc/httpd/conf.d/workers.properties,修改成以下內容:爲測試負載效果,不啓用stick_session。

worker.list=TomcatLB,statA
worker.statA.type=status
worker.TomcatLB.type=lb
worker.TomcatLB.sticky_session=false
worker.TomcatLB.balance_workers=TomcatA,TomcatB
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.175.4
worker.TomcatA.port=8009
worker.TomcatA.lbfactor=5
worker.TomcatB.type=ajp13
worker.TomcatB.host=192.168.175.5
worker.TomcatB.port=8009
worker.TomcatB.lbfactor=10

在mod_jk負載均衡中,後端tomcat的engine組件須要添加jvmRoute參數,該參數會爲當前server實例設置全局唯一標識符,所以每個實例的jvmRoute的值均不能相同,且jvmRoute的值必須等於balance_workers的成員值。對於上面的配置,Engine應該以下設置:此處還修改了name,但這不是要求要修改的。

<!--  在tomcatA上設置  -->
<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA">
<!--  在tomcatB上設置  -->
<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatB">

添加index.jsp,內容以下:

<%@ page language="java" %>
<html>
  <head><title>TomcatA</title></head>
  <body>
    <h1><font color="red">TomcatA </font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("abc","abc"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

會話管理器

  • 標準會話管理器(StandardManager)

​ 默認爲StandardManager

  • 持久會話管理器(PersistentManager)

    FileStore:保存至文件中的示例

    <Manager className="org.apache.catalina.session.PersistentManager"
             saveOnRestart="true">
        <Store className="org.apache.catalina.session.FileStore"
               directory="/data/tomcat-sessions" />
    </Manager>

​ JDBC:保存至JDBCStore中的示例

<Manager className="org.apache.catalina.session.PersistenManager"
         saveOnRestart="true">
    <Store className="org.apache.catalina.session.JDBCStore"
           driverName="com.mysql.jdbc.Driver"
           connectionURL="jdbc:mysql://localhost:3306/mydb?user=jb;password=pw" />
</Manager>
  • DeltaManager:經過多播同步session

    配置參考https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html

    分別在server.xml HOST標籤中添加以下:

    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                     channelSendOptions="8">
    
              <Manager className="org.apache.catalina.ha.session.DeltaManager"
                       expireSessionsOnShutdown="false"
                       notifyListenersOnReplication="true"/>
    
              <Channel className="org.apache.catalina.tribes.group.GroupChannel">
                <Membership className="org.apache.catalina.tribes.membership.McastService"
                            address="228.0.0.4"
                            port="45564"
                            frequency="500"
                            dropTime="3000"/>
                <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                          address="auto"
                          port="4000"
                          autoBind="100"
                          selectorTimeout="5000"
                          maxThreads="6"/>
    
                <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
                  <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
                </Sender>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
              </Channel>
    
              <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                     filter=""/>
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
    
              <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                        tempDir="/tmp/war-temp/"
                        deployDir="/tmp/war-deploy/"
                        watchDir="/tmp/war-listen/"
                        watchEnabled="false"/>
    
              <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
            </Cluster>

    注意:爲須要使用session cluster的webapps 開啓 session distribution功能

    在WEB-INF/web.xml中添加 <distributable />

    tomcat實現的session集羣,與負載均衡器無關

  • BackupManager:兩兩作成一個集羣

session集羣示例配置文件:

  1. TomcatA
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="node2.template.com" jvmRoute="TomcatA">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>

      <Host name="node2.template.com" appBase="/data/webapps" autoDeploy="true">
            <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">

          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="4000"
                      autoBind="100"
                      selectorTimeout="5000"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>
    <Context path="" docBase="ROOT" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/data/logs"
               prefix="node2_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>

    </Engine>
  </Service>
</Server>
  1. TomcatB

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
      Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements.  See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version 2.0
      (the "License"); you may not use this file except in compliance with
      the License.  You may obtain a copy of the License at
    
          http://www.apache.org/licenses/LICENSE-2.0
    
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
    -->
    <!-- Note:  A "Server" is not itself a "Container", so you may not
         define subcomponents such as "Valves" at this level.
         Documentation at /docs/config/server.html
     -->
    <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <!-- Security listener. Documentation at /docs/config/listeners.html
      <Listener className="org.apache.catalina.security.SecurityListener" />
      -->
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!-- Prevent memory leaks due to use of particular java/javax APIs-->
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
    
      <!-- Global JNDI resources
           Documentation at /docs/jndi-resources-howto.html
      -->
      <GlobalNamingResources>
        <!-- Editable user database that can also be used by
             UserDatabaseRealm to authenticate users
        -->
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
    
      <!-- A "Service" is a collection of one or more "Connectors" that share
           a single "Container" Note:  A "Service" is not itself a "Container",
           so you may not define subcomponents such as "Valves" at this level.
           Documentation at /docs/config/service.html
       -->
      <Service name="Catalina">
    
        <!--The connectors can use a shared executor, you can define one or more named thread pools-->
        <!--
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="150" minSpareThreads="4"/>
        -->
    
    
        <!-- A "Connector" represents an endpoint by which requests are received
             and responses are returned. Documentation at :
             Java HTTP Connector: /docs/config/http.html
             Java AJP  Connector: /docs/config/ajp.html
             APR (HTTP/AJP) Connector: /docs/apr.html
             Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
        -->
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
        <!-- A "Connector" using the shared thread pool-->
        <!--
        <Connector executor="tomcatThreadPool"
                   port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
        -->
        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
             This connector uses the NIO implementation. The default
             SSLImplementation will depend on the presence of the APR/native
             library and the useOpenSSL attribute of the
             AprLifecycleListener.
             Either JSSE or OpenSSL style configuration may be used regardless of
             the SSLImplementation selected. JSSE style configuration is used below.
        -->
        <!--
        <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" SSLEnabled="true">
            <SSLHostConfig>
                <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                             type="RSA" />
            </SSLHostConfig>
        </Connector>
        -->
        <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
             This connector uses the APR/native implementation which always uses
             OpenSSL for TLS.
             Either JSSE or OpenSSL style configuration may be used. OpenSSL style
             configuration is used below.
        -->
        <!--
        <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
                   maxThreads="150" SSLEnabled="true" >
            <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
            <SSLHostConfig>
                <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                             certificateFile="conf/localhost-rsa-cert.pem"
                             certificateChainFile="conf/localhost-rsa-chain.pem"
                             type="RSA" />
            </SSLHostConfig>
        </Connector>
        -->
    
        <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    
    
        <!-- An Engine represents the entry point (within Catalina) that processes
             every request.  The Engine implementation for Tomcat stand alone
             analyzes the HTTP headers included with the request, and passes them
             on to the appropriate Host (virtual host).
             Documentation at /docs/config/engine.html -->
    
        <!-- You should set jvmRoute to support load-balancing via AJP ie :
        <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
        -->
        <Engine name="Catalina" defaultHost="node1.template.com" jvmRoute="TomcatB">
    
          <!--For clustering, please take a look at documentation at:
              /docs/cluster-howto.html  (simple how to)
              /docs/config/cluster.html (reference documentation) -->
          <!--
          <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
          -->
    
          <!-- Use the LockOutRealm to prevent attempts to guess user passwords
               via a brute-force attack -->
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <!-- This Realm uses the UserDatabase configured in the global JNDI
                 resources under the key "UserDatabase".  Any edits
                 that are performed against this UserDatabase are immediately
                 available for use by the Realm.  -->
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
    
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
    
            <!-- SingleSignOn valve, share authentication between web applications
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
            -->
    
            <!-- Access log processes all example.
                 Documentation at: /docs/config/valve.html
                 Note: The pattern used is equivalent to using pattern="common" -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    
          </Host>
    
          <Host name="node1.template.com" appBase="/data/webapps" autoDeploy="true">
            <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                     channelSendOptions="8">
    
              <Manager className="org.apache.catalina.ha.session.DeltaManager"
                       expireSessionsOnShutdown="false"
                       notifyListenersOnReplication="true"/>
    
              <Channel className="org.apache.catalina.tribes.group.GroupChannel">
                <Membership className="org.apache.catalina.tribes.membership.McastService"
                            address="228.0.0.4"
                            port="45564"
                            frequency="500"
                            dropTime="3000"/>
                <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                          address="auto"
                          port="4000"
                          autoBind="100"
                          selectorTimeout="5000"
                          maxThreads="6"/>
    
                <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
                  <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
                </Sender>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
              </Channel>
    
              <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                     filter=""/>
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
    
              <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                        tempDir="/tmp/war-temp/"
                        deployDir="/tmp/war-deploy/"
                        watchDir="/tmp/war-listen/"
                        watchEnabled="false"/>
    
              <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
            </Cluster>
            <Context path="" docBase="ROOT" />
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/data/logs"
                   prefix="node1_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
          </Host>
    
        </Engine>
      </Service>
    </Server>
相關文章
相關標籤/搜索