tomcat

一、Tomcat简介

Tomcat,可以理解为实现Servlet和JSP的集合的容器。

Servlet:JAVA语言为了实现动态网站效果,实现CGI协议效果,在用户请求动态网页资源时,可以由web服务器将请求通过CGI协议转发至动态服务器,动态服务器在请求动态资源并在本地编译之后反馈给客户端,以实现动态效果。Servlet就是JAVA语言中的CGI协议。客户端将请求发送给服务器端,服务器将请求发送至Servlet,Servlet调用JDK将请求结果发还服务器,在由服务器相应。

JSP:JSP是简化实现Servlet的工具,Servlet编写规则十分复杂,要求程序员同时掌握JAVA开发及前端技能。JSP的出现简化了Servlet的难度,他可以在前端代码中嵌入JAVA语言。JSP在第一次运行时会编译成Servlet,然后编译成class文件,在JVM中执行出结果。

二、Tomcat组件说明

2.1 tomcat组件格式

<server>
  <service>
    <connector />
    <engine>
      <host>
        <context>
        </context>
      </host>
      <host>
      </host>
    </engine>
  </service>
</server>

2.2 常见组件说明

server:顶级组件,Tomcat的一个实例,通常一个JVM只能包含一个Tomcat实例。

service:服务组件,起关联作用,通常包含一个引擎(engine)和与此引擎相关联的一个或多个连接器(connector)。

connector:连接组件,负责连接客户端(可以是浏览器或Web服务器)请求至Servlet容器内的Web应用程序。

常用属性的说明:
address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;
maxThreads:支持的最大并发连接数,默认为200;
port:监听的端口,默认为0;
protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;
redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口;
connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为6000,即1分钟;
enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true;
acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中;

engine:容器类组件,处理请求的Servlet引擎组件,即Catalina Servlet引擎,它检查每一个请求的HTTP首部信息以辨别此请求应该发往哪个host或context,并将请求处理后的结果返回的相应的客户端。

host:容器类组件,主机组件类似于Apache中的虚拟主机,但在Tomcat中只支持基于FQDN的虚拟主机。一个引擎至少要包含一个host组件。

常用属性说明:
appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径;可以使用基于$CATALINA_HOME的相对路径;
autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true;

context:最内层的容器类组件,一个context代表一个web应用程序。配置一个Context最主要的是指定Web应用程序的根目录,以便Servlet容器能够将用户请求发往正确的位置。Context组件也可包含自定义的错误页,以实现在用户访问发生错误时提供友好的提示信息。

常用的属性定义有:
docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径;如果context定义在一个单独的xml文件中,此属性不需要定义;
reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false; 

2.3 其他组件

valve:拦截请求并在将其转至对应的webapp之前进行某种处理操作,类似于过滤器;可以用于任何容器中。

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进行工作;

logger

realm

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时用到的版本,过于老旧了。

 2.4 Tomcat主目录用途

/bin:存放windows或Linux平台上启动和关闭Tomcat的脚本文件

/conf:存放Tomcat服务器的各种全局配置文件,其中最重要的是server.xml和web.xml

/doc:存放Tomcat文档

/server:包含三个子目录:classes、lib和webapps

/server/lib:存放Tomcat服务器所需的各种JAR文件

/server/webapps:存放Tomcat自带的两个WEB应用admin应用和 manager应用

/common/lib:存放Tomcat服务器以及所有web应用都可以访问的jar文件

/shared/lib:存放所有web应用都可以访问的jar文件(但是不能被Tomcat服务器访问)

/logs:存放Tomcat执行时的日志文件

/src:存放Tomcat的源代码

/webapps:Tomcat的主要Web发布目录,默认情况下把Web应用文件放于此目录

/work:存放JSP编译后产生的class文件

三、tomcat配置

3.1 虚拟主机

tomcat的虚拟主机主要由<Host>和<Context>组件定义。

以下为简单示例:

<Host name="test" appBase="/home/data" unpackWARs="true" autoDeploy="true" >
  <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/home/data/logs"
    prefix="test_access_log" suffix=".txt"
    pattern="%h %l %u %t &quot;%r&quot; %s %b" />
  <Context path="" docBase="" />
  <Context path="/node1" docBase="node" />
</Host>

3.2 tomcat前增加反代,保证性能及安全性

前端反代工具可以使用Nginx、httpd、HAProxy等工具。

下面以httpd的最简单模型为例说明:

大概流程为:用户请求通过http协议发送给前端httpd程序,httpd程序通过http协议或者ajp协议反向代理给tomcat(具体来说是给tomcat的http connector或者ajp connector)

<VirtualHost *:80>
  ServerName localhost        #设置虚拟主机名
  ProxyVia Off                #在相应报文中的首部中添加反代信息
  ProxyRequests Off           #httpd仅能通知支持正向代理和反向代理中的一项,想使用反向代理必须显示关闭正向代理
  ProxyPreserveHost On        #向后端反向代理请求时,是否携带主机名信息(后端启动虚拟主机时有用)
  ProxyPass / http://200.168.10.102:8080/
  ProxyPassReverse / http://200.168.10.102:8080/    #用于让apache调整HTTP重定向响应报文中的Location、Content-Location及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器。

    <Location /status>
      SetHandler status
      Proxypass !         #对特定uri不进行反代
      Require all granted
    </Location>

  <Proxy *>
    Require all granted
  </Proxy>
  <Location  / >
    Require all granted
  </Location>
</VirtualHost>

四、tomcat集群

4.1 集群实现

 tomcat集群实现就是简单的LB集群搭建,创建两个以上的tomcat,tomcat前端加上负载均衡工具,如Nginx,httpd,haproxy等。

其实各反代工具中也有可以实现会话保持的功能,如Nginx使用upstream模块使用ip_hash功能,httpd使用proxy_module、proxy_balancer_module模块

4.2 会话保持

4.2.1 使用tomcat会话管理器

DeltaManager:通过多播(默认228.0.0.4)将会话信息同步给其他节点,实现单一节点上拥有全部会话信息。

BackupManager:与BackupManager相比,简单来说就类似于raid 0于raid 10。

配置方式

1、在特定应用的web.xml中添加 <distributable/>

2、如果使用的是mod_jk模块,请确保在您的engine上设置了jvmroute属性,并且jvmroute属性值与workers.properties中的worker名称匹配

 3、然后在 <Engine> 或<Host> 组件中添加相应配置。下面是官网中给的示例:

        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">

          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>
          <!--
          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   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"  #如果有多个IP的话,建议手动指定
                      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"/>
      #如果开启的tomcat的自动部署功能,还可以实现在一台tomcat上部署应用,自动部署到其他节点
          <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>

4.2.2 使用memcached缓存session

理论: 简单来说就是在tomcat后端部署一个或多个memcached服务,将会话session保存在mamcached中。

实践

1、下载相应jar包至tomcat的lib目录

  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

2、在<Context>组件中添加相应配置,如下:

           <Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">
              <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                memcachedNodes="n1:200.168.10.101:11211,n2:200.168.10.102:11211"
                failoverNodes="n1"  #故障转移节点,指明哪个节点是备用节点 
                requestUriIgnorePattern=".*.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
              />
             </Context>

3、测试。完成后添加负载均衡。

原文地址:https://www.cnblogs.com/9host/p/13739904.html