Apache 如何反向代理tomcat而且实现Session保持

简介html

LAMT=Linux+Apache+MySQL+Tomcat;前端

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器;java

在中小型系统和并发访问用户不是不少的场合下被广泛使用,是开发和调试JSP 程序的首选;mysql

 

架构需求linux

Tomcat实现JSP动态请求解析的基本架构web

说明:由后端Tomcat负责解析动态jsp请求,但为了提升响应性能,在同一主机内配置Apache作反向代理,转发全部请求至tomcat便可;正则表达式

完整的LNMT架构设计sql

wKiom1NrqReyIsVnAAXyNugPRuA080.jpg

说明:本篇博客主要讲解单台Haproxy到后端多台Tomcat服务器的实现;数据库

 

安装配置express

Tomcat安装配置

 

安装配置

Tomcat安装配置

安装JDK

复制代码
rpm -ivh jdk-7u9-linux-x64.rpm
vi /etc/profile.d/java.sh
    export JAVA_HOME=/usr/java/latest
    export PATH=$JAVA_HOME/bin:$PATH
. /etc/profile.d/java.sh
复制代码

安装Tomcat

tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/
cd /usr/local/
ln -sv apache-tomcat-7.0.42/ tomcat
vi /etc/profile.d/tomcat.sh
    export CATALINA_HOME=/usr/local/tomcat
    export PATH=$CATALINA_HOME/bin:$PATH
. /etc/profile.d/tomcat.sh
# 编写服务脚本
 vim /etc/rc.d/init.d/tomcat
#!/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/latest
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 ;;
configtest)
exec $CATALINA_HOME/bin/catalina.sh configtest ;;
*)
exec $CATALINA_HOME/bin/catalina.sh * ;;
esac
==========
chmod +x /etc/init.d/tomcat

配置Tomcat

vim /usr/local/tomcat/conf/server.xml

<?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">
<!-- 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" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- 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 (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL 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 HTTP/1.1 Connector on port 8443
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> # 这里咱们只启用AJP协议


<!-- 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="localhost" jvmRoute="TomcatB">

<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.101.69.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>
<!--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>
</Engine>
</Service>
</Server>

# tomcat session 复制集群 : 以上"灰色"的内容定义在Engine容器中,则表示对全部主机均启动用集群功能。若是定义在某Host中,则表示仅对此主机启用集群功能。此外,须要注意的是,Receiver中的address="auto"一项的值最好改成当前主机集群服务所对应的网络接口的IP地址.

route add -net  228.101.64.4   netmask 255.255.255.255 dev eth0  #添加相对应的组播路由; 

此外,全部启用集群功能的web应用程序,其web.xml中都须添加<distributable/>才能实现集群功能。若是某web应用程序没有本身的web.xml,也能够经过复制默认的web.xml至其WEB-INF目录中实现

 cp /usr/local/tomcat/conf/web.xml  /usr/local/tomcat/webapps/testapp/WEB-INF/

# vim web.xml
  95   <distributable/>
# 建立应用程序相关目录
cd /usr/local/tomcat/webapps/
mkdir -pv testapp/WEB-INF/{classes,lib}
cd testapp
vi index.jsp
<%@ page language="java" %>
<html>
  <head><title>Tomcat1</title></head># 在Tomcat2主机上替换为Tomcat2
  <body>
    <h1><font color="red">Tomcat1.lnmmp.com</font></h1>#  在Tomcat2主机上替换为,color修改成blue
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("lnmmp.com","lnmmp.com"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>





 

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组件 如上面示例文件中定义的: <Server port=”8005” shutdown=”SHUTDOWN”> 这会让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要包含一个引擎、一个或多个链接器。 如上面示例中的定义: <Service name=”Catalina”> 这定义了一个名为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链接器 # 这里咱们使用的是AJP1.3链接器;这个链接器只支持AJP协议; 4) proxy链接器 如上面示例server.xml中定义的HTTP链接器: <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443"/> 定义链接器时能够配置的属性很是多,但一般定义HTTP链接器时必须定义的属性只有“port”,定义AJP链接器时必须定义的属性只有"protocol",由于默认的协议为HTTP。如下为经常使用属性的说明: 1) address:指定链接器监听的地址,默认为全部地址,即0.0.0.02) maxThreads:支持的最大并发链接数,默认为200; 3) port:监听的端口,默认为0; 4) protocol:链接器使用的协议,默认为HTTP/1.1,定义AJP协议时一般为AJP/1.35) redirectPort:若是某链接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口; 6) connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟; 7) enableLookups:是否经过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true; 8) 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" />
4、Engine组件: Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。Engine须要defaultHost属性来为其定义一个接收全部发往非明肯定义虚拟主机的请求的host组件。如前面示例中定义的: <Engine name="Catalina" defaultHost="localhost"> 经常使用的属性定义: defaultHost:Tomcat支持基于FQDN的虚拟主机,这些虚拟主机能够经过在Engine容器中定义多个不一样的Host组件来实现;但若是此引擎的链接器收到一个发往非非明肯定义虚拟主机的请求时则须要将此请求发往一个默认的虚拟主机进行处理,所以,在Engine中定义的多个虚拟主机的主机名称中至少要有一个跟defaultHost定义的主机名称同名; name:Engine组件的名称,用于日志和错误信息记录时区别不一样的引擎; Engine容器中能够包含Realm、Host、Listener和Valve子容器。 5、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="mail.magedu.com" appBase="/web/mail">
    <Context path="" docBase="ROOT"/>
  </Host>
</Engine> 主机别名定义: 若是一个主机有两个或两个以上的主机名,额外的名称都可以以别名的形式进行定义,以下: <Host name="www.magedu.com" appBase="webapps" unpackWARs="true">
  <Alias>magedu.com</Alias>
</Host>
6、Context组件: Context在某些意义上相似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序;以下面的定义: <!-- Tomcat Root Context -->
    <Context path="" docBase="/web/webapps"/>
    
    <!-- buzzin webapp -->
    <Context path="/bbs" docBase="/web/threads/bbs" reloadable="true">
    </Context>
    
    <!-- chat server -->
      <Context path="/chat" docBase="/web/chat"/>
      
    <!-- darian web -->
    <Context path="/darian" docBase="darian"/> 在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; 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的配置: <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" />
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: <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; 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。

webapp体系结构:
wenapp有特定的组织格式:是一种层次目录结构;一般包含了servlet代码文件、jsp页面文件、类文件、部署描述符文件等等,通常会打包成归档格式;
/:web应用程序的根目录
/WEB-INF:此webapp的私有资源根目录。一般web.xml和context.xml均放置在次目录;
/WEB-INF:classes:此webapp自有类:
/WEB-INF:此webapp自有可以被打包为jar格式的类;

 
 

webapp的归档格式:
EJB类归档的扩展名为.jar
web应用程序的归档扩展名为.war
资源适配器的扩展名.rar
企业级应用程序的扩展名.ear
web服务的扩展名为.ear或.war

 

 

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的库文件已经在系统库文件的搜索路径内;
AJP(Apache JServ Protocol):
AJP(Apache JServ Protocol): AJP是面向数据包的基于TCP/IP的协议,它在Apache和Tomcat的实例之间提供了一个专用的通讯信道。目前经常使用AJP协议的版本是1.3,它主要有如下特征: 1) 在快速网络有着较好的性能表现,支持数据压缩传输; 2) 支持SSL,加密及客户端证书; 3) 支持Tomcat实例集群; 4) 支持在apache和tomcat之间的链接的重用;
配置apache经过mod_jk模块与Tomcat链接:
yum -y install httpd-devel # rpm -ql httpd-devel | grep apxs /usr/sbin/apxs 配置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/bin/apxs [root@www.magedu.com ~]# make && make install apache要使用mod_jk链接器,须要在启动时加载此链接器模块。为了便于管理与mod_jk模块相关的配置,这里使用一个专门的配置文件/etc/httpd/extra/httpd-jk.conf来保存相关指令及其设置。其内容以下: [root@localhost conf.d]# pwd
/etc/httpd/conf.d [root@localhost conf.d]# ls mod_dnssd.conf mod_jk.conf mod_proxy.conf.back README welcome.conf workers.properties ### [root@localhost conf.d]# cat 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 /* lbcA JkMount /status/ statA ########################################################################## 这里有配置文件能够直接复制使用,只须要更改IP便可 [root@localhost conf.d]# cat workers.properties worker.list=lbcA,statA worker.TomcatA.type=ajp13 worker.TomcatA.port=8009 worker.TomcatA.host=172.16.249.58 worker.TomcatA.lbfactor=1 worker.TomcatB.type=ajp13 worker.TomcatB.port=8009 worker.TomcatB.host=172.16.249.203 worker.TomcatB.lbfactor=1 worker.lbcA.type=lb worker.lbcA.sticky_session=0 worker.lbcA.balance_workers=TomcatA,TomcatB worker.statA.type = status

 

除了须要使用LoadModule指令在apache中装载模块外,mod_jk还须要在apache的主配置文件中设置其它一些指令来配置其工做属性。如JkWorkersFile则用于指定保存了worker相关工做属性定义的配置文件,JkLogFile则用于指定mod_jk模块的日志文件,JkLogLevel则可用于指定日志的级别(info, error, debug),此外还可使用JkRequestLogFormat自定义日志信息格式。而JkMount(格式: JkMount  <URL to match>  <Tomcat worker name>)指定则用于控制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 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/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的值均不能相同。 <Engine name=”Standalone” defaultHost=”localhost” jvmRoute=” TomcatA ”> 然后去配置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" %> <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> 演示效果,在TomcatB上某context中(如/test),提供以下页面 <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="blue">TomcatB </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>

 

配置apache经过模块与Tomcat链接:


要使用mod_proxy与Tomcat实例链接,须要apache已经装载mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(实现Tomcat集群时用到)等模块:

# httpd -D DUMP_MODULES | grep proxy httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
proxy_module (shared) proxy_balancer_module (shared) proxy_ftp_module (shared) proxy_http_module (shared) proxy_ajp_module (shared) proxy_connect_module (shared) Syntax OK # pwd
/etc/httpd/conf.d [root@localhost conf.d]# cat mod_proxy.conf ProxyVia on ProxyRequests off ProxyPreserveHost on <Proxy balancer://lb>
BalancerMember http://172.16.249.203:8080 loadfactor=1 route=TomcatA
BalancerMember http://172.16.249.58:8080 loadfactor=1 route=TomcatB
</Proxy> ProxyPass / balancer://lb/ stickysession=JSESSIONID 
ProxyPassReverse / balancer://lb/

<Location /> Order Allow,Deny Allow from all </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> ProxyPassReverse:用于让apache调整HTTP重定向响应报文中的Location、Content-Location及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器。

 

 

测试:

配置apache经过mod_jk模块与Tomcat链接时还可以监控后端server 的状态信息
JkLogFile logs/mod_jk.log
JkLogLevel notice
JkMount /* lbcA JkMount /status/ statA # 

相关文章
相关标签/搜索