tomcat

web container:
JDK, Servlet, JSP

商業實現:
WebSphere(IBM)
WebLogic (BEA --> Orace)
Oc4j
Glassfish
Geronimo
JOnAS
JBoss

開源實現:
Tomcat
Jetty
Resin

jsp --> jasper --> servlet(PAGE_jsp.java) --> complier --> bytecode (PAGE_jsp.class) --> JVM

tomcat: JWS + Jserv
catalina

jdk + tomcat

tomcat的組件:server.xml
<Server>
<Service>
<connector/>
<connector/>
<Engine>
<Host />
<Host>
<Context/>
...
</Host>
</Engine>
</Service>
</Server>

每個組件,均有java類來實現;

此些組件可分爲如下幾類:
頂級組件:Server
服務類:Service
連接器:http, https, ajp(apache jserv protocol)
容器類:Engine, Host, Context
被嵌套的組件:valve, logger, realm, loader, manager
集羣類組件:listener, ...

安裝:
(1) 系統自帶的openjdk+tomcat;

yum install java-1.7.0-openjdk

yum install java-1.7.0-openjdk-devel

yum install tomcat tomcat-admin-webapps tomcat-webapps

vim /etc/profile.d/java.sh

export JAVA_HOME=/usr/bin

source /etc/profile.d/java.sh

默認連接器:
http, 8080
ajp, 8009

(2) 使用Oracle JDK和tomcat主站提供的編譯完成的程序包
rpm -ivh jdk-8u25-linux-x64.rpm

tar xf apache-tomcat-VERSION-tar.gz -C /usr/local
cd /usr/local
ln -s apache-tomcat-VERSION tomcat

tomcat的目錄結構:
bin: 腳本及啓動時用到類;
lib:類庫;
conf:配置文件;
logs:日誌文件;
webapps:webapp的默認部署目錄;
work:工作目錄;
temp:臨時文件目錄;

tomcat的配置文件:
server.xml:主配置文件;
context.xml:每個webapp都可以有專用的配置文件,這些配置文件通常位於webapp程序目錄下的WEB-INF目錄中,用於定義會話管理順序、JDBC等 ;conf/context.xml是爲各webapp提供默認配置;
web.xml:每個webapp只有在“部署”之後才能夠被訪問;此文件則用於爲各webapps定義默認的部署操作方式;
tomcat-users.xml:用戶認證的賬號和密碼配置文件;
catalina.policy:當使用-security選項來啓動tomcat實例時會讀取此配置文件來實現基於安全策略的運行方式;
catalina.properties:Java屬性的定義文件,用於設定類加載器路徑等 ,以及一些與JVM性能相關的調優參數;
logging.properties:日誌系統相關的配置;

Java Webapp的組織結構:
有特定的組織形式、層次型的目錄結構;主要包含了servlet代碼文件、JSP頁面文件、類文件、部署描述符文件等 ;
/:webapps的根目錄
index.jsp:jsp的主頁面文件
WEB-INF/:當前webapp的私有資源目錄,通常存放當前webapp自用的web.xml;
META-INF/:當前webapp的私有資源目錄,通常存儲當前webapp自用的context.xml;
classes/: 當前webapp的私有類;
lib/:當前webapp的私有類,被打包成jar格式;

webapp歸檔格式:
.war:webapp;
.jar:EJB的類打包文件;
.rar:資源適配器類打包文件;
.ear:企業級應用程序;

手動添加一個測試應用程序:其目錄爲webapps(默認爲/var/lib/tomcat/webapps/)
1、創建webapp特有的目錄結構;

mkdir -pv myapp/{classes,lib,WEB-INF,META-INF}

2、提供webapp的測試頁面:

myapp/index.jsp

<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>JSP Test Page</title>
</head>
<body>
<% out.println("hello world");
%>
</body>
</html>

部署(deploy)webapp的相關操作:
deploy:將webapp的源文件放置於目標目錄、配置tomcat服務器能夠基於context.xml文件中定義的路徑來訪問此webapp;將其特有的類通過class loader裝載至tomcat:
有兩種方式:
自動部署:auto deploy
手動部署:
(1) 冷部署:把webapp複製到指定位置,而後才啓動tomcat;
(2) 熱部署:在不停止tomcat的前提下進行的部署:
部署工具:manager app、ant腳本、tcd(Tomcat Client Deployer)等;
undeploy:反部署,停止webapp,並從tomcat實例上拆除其部署文件和部署名;
stop:停止,不再向用戶提供服務;
start:啓動處於“停止”狀態的webapp;
redeploy:重新部署;

tomcat-admin-webapps包自帶的應用程序:
manager app: webapp管理工具;
host manager: VHosts管理工具;

授權用戶訪問manager、status、host manager:由配置文件tomcat-users.xml定義;

vim /etc/tomcat/tomcat-users.xml

<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user name="admin" password="adminadmin" roles="manager-gui,"/>

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
admin-gui - allows access to the HTML GUI
admin-script - allows access to the text interface

tomcat: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/lastest
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME

case $1 in
start)
exec $CATALINA_HOME/bin/catalina.sh start ;;
stop)
exec $CATALINA_HOME/bin/catalina.sh stop;;
restart)
$CATALINA_HOME/bin/catalina.sh stop
sleep 2
exec $CATALINA_HOME/bin/catalina.sh start ;;
*)
echo "Usage: basename $0 {start|stop|restart}"
exit 1
;;
esac

tomcat的常用組件:
每個組件幾乎都是通過特有的類來實現,而且有的組件還不止一種實現方式;

Server:tomcat實例,即運行的一個jvm進程;監聽於8005端口接收“SHUTDOWN”。各server監聽的端口不能相同,因此,一個物理主機上啓動多個server實例應該使用不同的端口;

service:用於實現將一個或多個connector關聯至一個engine;

connector組件:
進入tomcat的請求可分爲兩類:
1、tomcat做爲獨立的應用程序服務器:standalone,此時,請求將來自於瀏覽器;
http, https
2、tomcat做爲應用程序服務器:請求將來自於前面反代主機;
httpd: http, https, ajp
nginx: http, https

connector常用的屬性:
address:監聽的IP地址;
maxThreads:最大併發連接數,默認爲150;
port:監聽的端口;
protocol:連接器使用的協議,一般爲HTTP/1.1或AJP/1.3;
redirecPort:重定向端口;
connectionTimeout:連接的超時時長,單位爲毫秒,默認爲60000;
enableLookups:是否通過dns查詢;
acceptCount:定義等待隊列的長度;
scheme:客戶端請求標識;
debug:
secure:安全模式;
clinetAuth:客戶端認證;
sslProtocol:ssl協議版本 建議TLS;

Engine:Servlet的一個實例,即servlet引擎,其內部可以有一個或多個Host組件來定義站點;通常需要通過defaultHost的屬性定義默認虛擬主機;

屬性:
name=Catalina
defaultHost=            :定義默認虛擬主機;
jvmRoute=                :定義jvm路由方式

Host組件:
位於Engine容器中用於接收請求並進行相應處理的主機或虛擬主機,如前面示例中的定義:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>

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

虛擬主機定義示例:

<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps">
<Context path="" docBase="ROOT"/>
<Context path="/bbs" docBase="/web/bss"
reloadable="true" crossContext="true"/>
</Host>

<Host name="node2.magedu.com" appBase="/data/webapps">
</Host>
</Engine>

爲第二個虛擬主機提供測試webapp:
mkdir -pv /data/webapps/ROOT/{classes,lib,WEB-INF,META-INF}

主機別名定義:
如果一個主機有兩個或兩個以上的主機名,額外的名稱均可以以別名的形式進行定義,如下:
<Host name="www.magedu.com" appBase="webapps" unpackWARs="true">
<Alias>magedu.com</Alias>
</Host>

Context組件:
Context在某些意義上類似於apache中的路徑別名,一個Context定義用於標識tomcat實例中的一個Web應用程序;如下面的定義:
示例:
<Host name="node2.magedu.com" appBase="/data/webapps">
<Context path="/test" docBase="testapp" reloadable="true"/>
</Host>

在Tomcat6中,每一個context定義也可以使用一個單獨的XML文件進行,其文件的目錄爲$CATALINA_HOME/conf/<engine name>/<host name>。可以用於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;

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的配置:
<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>

下面是一個使用JDBC方式獲取用戶認證信息的配置:
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority"
connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name"
userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />

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:
<Context path="/probe" docBase="probe">
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1"/>
</Context>

其中相關屬性定義有:
1) className:相關的java實現的類名,相應於分別應該爲org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;
2) allow:以逗號分開的允許訪問的IP地址列表,支持正則表達式,因此,點號“.”用於IP地址時需要轉義;僅定義allow項時,非明確allow的地址均被deny;
3) deny: 以逗號分開的禁止訪問的IP地址列表,支持正則表達式;使用方式同allow;

示例:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="node2_access_log" suffix=".log"
pattern="%h %l %u %t "%r" %s %b" />

<Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="172.16.100.67"/>

tomcat動靜分離方式:借用反向代理分流:

一、LNMT:
Client --> http --> Nginx --> reverse_proxy (http) --> tomcat (http connector)

location / {
root /usr/share/nginx/html;
index  index.html index.htm;
}

location ~* .(jsp|do)$ {
proxy_pass http://app1.magedu.com:8080;
}

二、LAMT:
Client --> http --> httpd --> reverse_proxy_module (http) --> tomcat (http connector)
Client --> http --> httpd --> reverse_proxy_module (ajp) --> tomcat (ajp connector)

第一種方式:proxy_module, proxy_http_module
第二種方式:proxy_module, proxy_ajp_module

(1) 第一種方式的配置機制,使用虛擬主機;(備註博客屏蔽ss R字樣)
<VirtualHost :80>
ServerName tc1.magedu.com
ProxyRequests Off //關閉正向代理
ProxyVia On //響應報文提供Via信息,即由誰代理的
ProxyPreserveHost On //保留請求的主機名信息傳遞給後端服務器
<Proxy
>
Require all granted //什麼人能訪問此代理
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPa***everse / http://localhost:8080/
<Location />
Require all granted //授權訪問根的請求
</Location>
</VirtualHost>

(2)

<VirtualHost :80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy
>
Require all granted
</Proxy>
ProxyPass / ajp://node2.magedu.com:8009/
ProxyPa***everse / ajp://node2.magedu.com:8009/
<Location />
Require all granted
</Location>
</VirtualHost>

Client --> http --> httpd --> mod_jk (ajp) --> tomcat (ajp connector)

tomcat cluster:

會話保持:
(1)session sticky:
source ip
cookie
hash
(2)session cluster
(3)session server

        一、apache + tomcat組合:

                    配置apache通過mod_proxy模塊與Tomcat連接,要使用mod_proxy與Tomcat實例連接,需要apache已經裝載mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(實現Tomcat集羣時用到)等模塊:
                    1、apache結合tomcat的http連接器:在httpd.conf的全局配置段或虛擬主機中添加如下內容:
                                                ProxyVia Off
                                                ProxyRequests Off
                                                ProxyPass / http://172.16.100.1:8080/
                                                ProxyPa***everse / http://172.16.100.1:8080/
                                                <Proxy *>
                                                    Require all granted
                                                </Proxy>
                                                <Location  / >
                                                    Require all granted
                                                </Location>

                    2、apahce結合tomcat的ajp連接器:在httpd.conf的全局配置段或虛擬主機中添加如下內容:
                                                ProxyVia Off
                                                ProxyRequests Off
                                                ProxyPreserveHost Off
                                                <Proxy *>
                                                    Require all granted
                                                </Proxy>
                                                    ProxyPass  /  ajp://172.16.100.1:8009/
                                                    ProxyPa***everse  /  ajp://172.16.100.1:8009/
                                                <Location  / >
                                                    Require all granted
                                                </Location>

                        關於如上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指令直接進行設置,如:
                                        <Proxy balancer://hotcluster>
                                            BalancerMember  http://www1.magedu.com:8080 loadfactor=1
                                            BalancerMember  http://www2.magedu.com:8080 loadfactor=2
                                            ProxySet  lbmethod=bytraffic
                                        </Proxy>

                                        ProxyPa***everse:用於讓apache調整HTTP重定向響應報文中的Location、Content-Location及URI標籤所對應的URL,在反向代理環境中必須使用此指令避免重定向報文繞過proxy服務器。                       

                    啓用balancer-manager管理接口:
                                                    <Location  /balancer-manager>
                                                                SetHandler   balancer-manager
                                                                ProxyPass   !
                                                                Require all  granted
                                                    </Location>

    3、配置apache通過mod_jk模塊與Tomcat連接,mod_jk是第三方模塊,是早期還沒mod_proxy之前,實現tomcat的負載均衡,其官網https://tomcat.apache.org/download-connectors.cgi
                apxs由httpd-devel包提供;        
                        # tar xf tomcat-connectors-1.2.44-src.tar.gz 
                        # cd tomcat-connectors-1.2.44-src/native/
                        # ./configure --with-apxs=/usr/bin/apxs 
                        # make && make install

                        apache要使用mod_jk連接器,需要在啓動時加載此連接器模塊。爲了便於管理與mod_jk模塊相關的配置,這裏使用一個專門的配置文件/etc/httpd/conf.d/httpd-jk.conf來保存相關指令及其設置。其內容如下:
                                # Load the mod_jk
                                LoadModule  jk_module  modules/mod_jk.so
                                JkWorkersFile  /etc/httpd/conf.d/workers.properties
                                JkLogFile  logs/mod_jk.log
                                JkLogLevel  debug
                                JkMount  /*  TomcatA
                                JkMount  /status/  stat1

                        workers.properties文件一般由兩類指令組成:一是mod_jk可以連接的各worker名稱列表,二是每一個worker的屬性配置信息。它們分別遵循如下使用語法。

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

                        其中worker.list指令可以重複指定多次,而worker name則是Tomcat中engine組件jvmRoute參數的值。如:
                        worker.TomcatA.host=172.16.100.1

                        根據其工作機制的不同,worker有多種不同的類型,這是需要爲每個worker定義的一項屬性woker.<work name>.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/conf.d/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服務即可生效。

            二、tomcat搭建session cluster:
                                Tomcat基於內存複製的集羣
            (1)配置啓用集羣,另外注意engine的jvmRoute=需定義跟前端調度器一致;
    <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.MessageDispatch15Interceptor"/>
      </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.JvmRouteSessionIDBinderListener"/>
      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
    </Cluster>

以上內容定義在Engine容器中,則表示對所有主機均啓動用集羣功能。如果定義在某Host中,則表示僅對此主機啓用集羣功能。此外,需要注意的是,Receiver中的address="auto"一項的值最好改爲當前主機集羣服務所對應的網絡接口的IP地址。

            (2)配置webapps
                            # cp /etc/tomcat/web.xml   WEB-INF/
                            vim     WEB-INF/web.xml     在<web-app>的標籤內添加<distributable/>;

            三、session server;

            session會話保持之session服務器

            前提:
            兩個tomcat節點:172.16.100.7(tomcatA.magedu.com),172.16.100.8(tomcatB.magedu.com)
            兩個memcached節點:172.16.100.9, 172.16.100.10
            一個負載均衡節點:172.16.100.6

            Clients-->172.16.100.6-->(tomcatA, tomcatB)

            memcached-session-manager項目地址,http://code.google.com/p/memcached-session-manager/

            下載如下jar文件至各tomcat節點的tomcat安裝目錄下的lib目錄中,其中的${version}要換成你所需要的版本號,tc${6,7,8}要換成與tomcat版本相同的版本號。
                memcached-session-manager-${version}.jar
                memcached-session-manager-tc${6,7,8}-${version}.jar
                spymemcached-${version}.jar
                msm-javolution-serializer-${version}.jar
                javolution-${version}.jar

            分別在兩個tomcat上的某host上定義一個用於測試的context容器,並在其中創建一個會話管理器,如下所示:

                                 <Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">
                                        <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                                            memcachedNodes="n1:172.16.100.9:11211,n2:172.16.100.10:11211"
                                            failoverNodes="n1"
                                            requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                                            transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
                                        />
                                     </Context>

            分別爲兩個context提供測試頁面:

            tomcatA:
            # mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
            # vim /usr/local/tomcat/webapps/test/index.jsp
            添加如下內容:
            <%@ page language="java" %>
            <html>
                <head><title>TomcatA</title></head>
                <body>
                    <h1><font color="red">TomcatA.magedu.com</font></h1>
                    <table align="centre" border="1">
                        <tr>
                            <td>Session ID</td>
                    <% session.setAttribute("magedu.com","magedu.com"); %>
                            <td><%= session.getId() %></td>
                        </tr>
                        <tr>
                            <td>Created on</td>
                            <td><%= session.getCreationTime() %></td>
                     </tr>
                    </table>
                </body>
            </html>

            tomcatB:
            # mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
            # vim /usr/local/tomcat/webapps/test/index.jsp
            添加如下內容:
            <%@ page language="java" %>
            <html>
                <head><title>TomcatB</title></head>
                <body>
                    <h1><font color="blue">TomcatB.magedu.com</font></h1>
                    <table align="centre" border="1">
                        <tr>
                            <td>Session ID</td>
                    <% session.setAttribute("magedu.com","magedu.com"); %>
                            <td><%= session.getId() %></td>
                        </tr>
                        <tr>
                            <td>Created on</td>
                            <td><%= session.getCreationTime() %></td>
                     </tr>
                    </table>
                </body>
            </html>

            在172.16.100.6上配置反向代理的負載均衡內容,類似如下所示:
            <Proxy balancer://tomcat>
                    BalancerMember  http://172.16.100.7:8080 loadfactor=1
                    BalancerMember  http://172.16.100.8:8080 loadfactor=1
                    ProxySet  lbmethod=byrequests
            </Proxy>

            ProxyVia Off
            ProxyRequests Off
            ProxyPass / balancer://tomcat/
            ProxyPa***everse / balancer://tomcat/
            <Proxy *>
                    Order Allow,Deny
                    Allow From all
            </Proxy>

            <Location />
                    Order Allow,Deny
                    Allow From all
            </Location>

            測試結果,在瀏覽器中訪問http://172.16.100.6/test,結果如下所示,其session ID在負載均衡環境中保持不變。

            TomcatA.magedu.com

            Session ID  4DD0340CE6294FF2BBE802CD4CD039EC-n2
            Created on  1399890838103

            TomcatB.magedu.com

            Session ID  4DD0340CE6294FF2BBE802CD4CD039EC-n2
            Created on  1399890838103

分佈式系統:
1、系統的各組件分佈於網絡上多個計算機;
2、各組件彼此之間僅僅通過消息傳遞來通信並協調行動;

        分佈式系統存在的意義:
                        1、向上擴展的性價比越來越低;
                        2、單機擴展存在性能上升臨界點;
                        3、出於穩定性及可用性考慮,單機會存在多方面的隱患;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章