一、tomcat配置文件:

1、server.xml:核心配置文件,在上面初级中已介绍。

2、context.xml:上下文配置文件,为部署于此tomcat实例上的所有webApp(web应用程序)提供默认配置文件;

context.xml常用于定义会话管理器、JDBC以及Realm等。但每个webApp均可有自己独有的context.xml,

通常放置于每个webApp目录的META-INF。

3、web.xml:为部署于此tomcat实例上的所有webApp提供默认部署描述符;通常用于为webapp提供基本的servlet定义和MIME映射表等。

4、tomcat-users.xml:在上面初级中已介绍。

5、catalina.policy:java安全策略配置文件,当基于security选项启动tomcat实例时,会读取此配置文件。

6、catalina.properties:java属性定义文件,设定类加载路径、安全包列表和一些调整性能的参数信息。

7、logging.properties:日志相关的配置文件,日志级别、路径等。


二、tomcat部署方式:部署是指将webApp以及其所依赖类库等装载进tomcat实例上,以便接收用户请求。


1、静态方式:在tomcat启动前进行的webapp部署,静态方式是常用的部署方式。

2、动态方式:在不打断tomcat运行的前提下,通过tomcat manager或者其他的命令行工具进行的部署。


三、webapp体系结构:webapp有其特定的组织格式,是一种层次型目录结构。

1、/:webApp的根目录。

2、/WEB-INF:此webapp的私有资源目录(即用户通过浏览器不能直接访问),通常web.xml和context.xml均放置于此处。

3、/WEB-INF/classes:此webapp的自有的类。

4、/WEB-INF/lib:此webapp的自有的jar包。

5、/META-INF:此webapp的私有资源目录,并不是所有的webapp都有此目录。


四、Tomcat的运行方式:


1、单独配置(Standalone Configure):由tomcat自己完成http请求的全过程。

(1)、完成http请求。

(2)、处理静态文件(css、js、p_w_picpath等)。

(3)、处理动态jsp文件。


2、进程间配置:Apache/Nginx、Tomcat在同一台主机上完成http请求,实现动静分离。

(1)、Apache/Nginx接收http请求。

(2)、Apache/Nginx处理静态文件(css、js、p_w_picpath等)。

(3)、Tomcat处理动态jsp文件。

(4)、通过connector(http协议、AJP协议)使Apache/Nginx和Tomcat建立关联。


3、独立/网络配置:Apache/Nginx、Tomcat在不同主机上完成http请求,实现动静分离。

(1)、Apache/Nginx接收http请求。

(2)、Apache/Nginx处理静态文件(css、js、p_w_picpath等)。

(3)、Tomcat处理动态jsp文件。

(4)、通过connector(http协议、AJP协议)使Apache/Nginx和Tomcat建立关联。


五、Apache与Tomcat连接器通信的模块有两个:


1、mod_jk:apache1.3,apache2.0

   可以基于http、ajp协议与tomcat进行通信,但一般用ajp协议。

2、mod_proxy:apache2.2+(不过2.2+可以手工编译mod_jk)

   可以基于http、ajp协议与tomcat进行通信。

3、mod_jk VS mod_proxy:

(1)、均可实现负载均衡,在实现负载均衡效果上mod_proxy稍弱那么一点点,但mod_proxy特性定制上比较强大。

(2)、均支持基于web页面来管理接口。

(3)、兼容性,mod_proxy已经成为Apache的标准模块,mod_jk需要额外手工安装。

(4)、配置:mod_proxy简单,mod_jk麻烦。

(5)、协议:mod_jk(ajp),mod_proxy(http/https、ajp)。


五、Tomcat的http连接器类型:


1、基于Java的HTTP1.1连接器,默认。

   <connector port="8080" protocol="http/1.1" .../>

2、基于Java的高性能NIO HTTP/1.1连接器(但还不成熟,可能存在bug)。

 <connector port="8080" protocol="org.apache.coyote.http11.Http11NIOProtocol" .../>

3、基于C/C++研发的Native APR HTTP/1.1连接器,在负载较大时一般使用此连接器,但为tomcat需要额外安装APR组件。

 <connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" .../>


六、LAMT和LNMT:

1、LAMT(Linux+Apache+MySql+Tomcat):

(1)、Apache(mod_jk,ajp)+Tomcat(ajp connector)

(2)、Apache(mod_proxy,ajp、http/https)+Tomcat(ajp、http/https connector)

2、LNMT(Linux+Nginx+MySql+Tomcat):

  Nginx+Tomcat(http/https connector)


七、LNMT详解:

1、Nginx + 1个Tomcat:

(1)、动、静均有tomcat处理:

   #vim /etc/nginx/nginx.conf, 编辑

   location / {

     #root /usr/share/nginx/html;

     #index index.html index.htm;

     proxy_pass http://192.168.10.6:8088;

   }

(2)、动、静分离,但静态文件由Nginx处理:

   #vim /etc/nginx/nginx.conf, 编辑

   location / {

     root /web/htdocs;

     index index.html index.htm index.jsp;

   }

   

   location ~* \.(jsp|do)$ {

     proxy_pass http://192.168.10.6:8088;

   }

(3)、动、静分离,但静态文件由单独的服务器处理:

   #vim /etc/nginx/nginx.conf, 编辑

   location / {

     root /web/htdocs;

     index index.html index.htm;

   }

   

   location ~* \.(jsp|do)$ {

     proxy_pass http://192.168.10.6:8088;

   }  


   location ~* \.(jpg|jpeg|png|gif|doc|pdf|zip|rar|exe)$ {

     proxy_pass http://192.168.10.8:8088;

   }


2、Nginx + 2个Tomcat:

第一步:

http{

 upstream tomcat {

     server 192.168.10.6:8080;

     server 192.168.10.8:8080;

 }

第二步:

 server{

   location ~* \.(jsp|do)$ {

     proxy_pass http://tomcat;

   }

 }


}

八、LAMT详解:

注意:关闭正向代理(ProxyRequests off ),启动反向代理(ProxyPass)

1、Apache + 1个Tomcat实现反向代理:

(1)、mod_proxy(http.https,ajp)

     /etc/httpd/conf.d下添加配置mod_proxy.conf,其内容如下:

A、使用ajp进行连接,ajp://192.168.10.6:8009中的8009要和 tomcat中的AJP连接器(<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />)的端口8009保持一致:

ProxyVia on :用于控制在http首部是否使用Via,主要用于在多级代理中控制请求的流向。默认为off

ProxyRequests off 关闭正向代理

ProxyPreserveHost on

#启动反向代理 

ProxyPass /p_w_picpaths  !  ,注意:!为取反,即不进行代理

ProxyPass /css !

ProxyPass /js !

ProxyPass /  ajp://192.168.10.6:8009/ 

ProxyPassReverse  /  ajp://192.168.10.6:8009/


<Location />

  Order Allow,Deny

  Allow from all

</Location>

B、使用http进行连接,http://192.168.10.6.8080中的8080要和tomcat中的http连接器(

    <Connector port="8080" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443" />

)的端口8080保持一致 :

ProxyVia on

ProxyRequests off 关闭正向代理

ProxyPreserveHost on

#启动反向代理

ProxyPass / http://192.168.10.6.8080/

ProxyPassReverse / http://192.168.10.6.8080/

<Location />

  Order Allow,Deny

  Allow from all

</Location>

C、备注:ProxyPassReverse 用于让apache调整http重定向响应报文中的location、content-Location以及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器,ProxyPassReverse 和ProxyPass 保持一致。

D、httpd作为tomcat的反向代理时有时会报如下错误这种问题往往是由于Apache没有转发的权限导致的,解决方法:# /usr/sbin/setsebool -P httpd_can_network_connect 1 即可。tomcat--高级_tomcat

(2)、mod_jk(ajp)(注意需要手工编译安装mok_jk:mod_jk是ASF的一个项目,是一个工作于apache端基于AJP协议与tomcat通信的连接器,它是apache的一个模块。

A、编译安装mod_jk:

    #tar xf tomcat-connector-1.2.37.-src.tar.gz

    #cd tomcat-connector-1.2.37.-src/native

    #./configure --with-apxs=/usr/local/apache/bin/apxs

    #make && make install

   注意:apxs是apache安装第三方软件的钩子,即想要安装第三方软件必须安装apxs,

             查下是否已安装apxs:rpm -ql  httpd-devel |grep apxs ,查看结果如下:

         [root@www ~]# rpm -ql  httpd-devel |grep apxs

          /usr/sbin/apxs,则上面的--with-apxs路径要和apxs的安装路径一致

            #./configure --with-apxs= /usr/sbin/apxs

          如未安装要先安装apxs(apxs在httpd-devel中)#yum -y install httpd-devel

            

B、配置mod_jk,mod_jk.conf内容如下:

   LoadModule jk_module modules/mod_jk.so

   JkWordersFile /etc/httpd/conf.d/worders.properties

   JkLogFile logs/mod_jk.log

   JkLogLevel notice

   JkMount /*  TomcatA

   JkMount /status/ statA


   worders.properties的内容如下:

   worker.list=TomcatA,statA

   worker.TomcatA.type=ajp13

   worker.TomcatA.port=8009

   worker.TomcatA.host=192.168.10.6

   worker.TomcatA.lbfactor=1

   worker.statA.type=status


2、Apache + 2个Tomcat:

*推荐使用mod_proxy方式实现反向代理和负载均衡。

(1)mod_jk(ajp)实现实现反向代理和负载均衡。

   mod_jk.conf内容如下:

   LoadModule jk_module modules/mod_jk.so

   JkWordersFile /etc/httpd/conf.d/worders.properties

   JkLogFile logs/mod_jk.log

   JkLogLevel notice

   JkMount /* /lbclusterA

   JkMount /status statA


   worders.properties的内容如下:

   worker.list=lbclusterA,statA

   worker.TomcatA.type=ajp13

   worker.TomcatA.port=8009

   worker.TomcatA.host=192.168.10.6

   worker.TomcatA.lbfactor=1

   worker.TomcatB.type=ajp13

   worker.TomcatB.port=8009

   worker.TomcatB.host=192.168.10.7

   worker.TomcatB.lbfactor=1

   worker.lbclusterA.type=lb

   worker.lbclusterA.sticky_session=0

   worker.lbclusterA.balance_workers=TomcatA,TomcatB

   worker.statA.type=status


(2)、mod_proxy(http.https,ajp)实现反向代理和负载均衡。


A、配置mod_proxy.conf内容如下:

ProxyVia on

ProxyRequests off

ProxyPreserveHost on

<!--loadfactor为权重-->

<!--lbmethod为调度方法-->

<Proxy  balancer://lb>

 BalancerMember http://192.168.10.6.8080 loadfactor=1 route=TomcatA

 BalancerMember http://192.168.10.7.8080 loadfactor=1 route=TomcatB

 ProxySet lbmethod=bytraffic

</Proxy> 

<!--stickysession实现Session绑定-->

ProxyPass / balancer://lb/ stickysession=JSESSIONID

ProxyPassReverse / balancer://lb/

<Location />

  Order Allow,Deny

  Allow from all

</Location>

B、说明:

负载均衡,且实现会话绑定时要注意给每个tomcat实例的egine容器定义一个jvmRoute属性,

如上tomcatA、tomcatB,此名称要跟前端调度模块中使用的名称保持一致。

另外,在mod_proxy实现负载均衡的会话绑定时,还要使用stickysession=JSESSIONID(JSESSIONID字符要大写)。

#min:连接池的最小容量

#max:连接池的最大容量

#loadfactor:用于负载均衡集群配置中,定义对应后端服务器的权重,取值范围1~100

#retry:当apache将请求发送至后端服务器得到错误响应时等待多长时间后再重试,单位为秒。

ProxySet lbmethod=byrequests 为实现负载均衡的方式,共有三种类型

#lbmethod=byrequests 按照请求次数均衡(默认) 

#lbmethod=bytraffic 按照流量均衡 


#lbmethod=bybusyness 按照繁忙程度均衡(总是分配给活跃请求数最少的服务器)


tomcat--高级_tomcat_02

tomcat--高级_tomcat_03

C、问题:

stickysession的方式将用户会话绑定在一直绑定在同一台机器上,可见破坏了负载均衡的初衷,要想实现真正的负载均衡需要处理对session会话进行更友好的管理如session复制或者session服务器Memcached、Redis等),已达到真正实现负载均衡。


九、tomcat会话管理:

1、StandardManager:

是tomcat6、7默认的会话管理器,

用于非集群环境中对单个处于运行状态的tomcat实例会话进行管理。

当tomcat正常关闭时(stop命令关闭),这些会话相关的数据会被写入磁盘上的一个名叫

sessions.ser的文件中,并在tomcat下次启动时读取此文件。

缺陷:

用于非集群环境。

当tomcat非正常关闭时会话数据会丢失。

<Manager

 className="org.apache.catalina.session.StandardManager"

 pathname="..."

 maxInaciveInterval="7200"/>

maxInaciveInterval非活动的会话超时时长,默认为60s

pathname:会话文件的保存目录,默认保存于$CATALINA_HOME/work/Catalina/<hostname>/下的sessions.ser中

2、PersistentManager:

用于非集群环境中对单个处于运行状态的tomcat实例会话进行管理。当一个会话长时间处于

空闲状态时会被写入到swap会话对象中,这对于内存资源比较吃紧的应用环境来说比较有用。

将会话数据保存至持久存储中,并且能在服务器意外终止后重新启动时重新加载这些会话信息。

持久会话管理器支持将会话保存至文件或者db中。

缺陷:

用于非集群环境。

当tomcat非正常关闭时会话数据会丢失。

<Manager

 className="org.apache.catalina.session.PersistentManager

 saveOnRestart="true">

 <Store className="org.apache.catalina.session.FileStore"

 directory="/data/tomcat-sessions"/>

</Manager>


<Manager

 className="org.apache.catalina.session.PersistentManager

 saveOnRestart="true">

 <Store className="org.apache.catalina.session.JDBCStore"

 driverName="com.mysql.jdbc.Driver"

 connectionURL="jdbc:mysql://localhost:3306/mydb?user=test;password=test"/>

</Manager>


3、DeltaManager:

用于tomcat集群的会话管理器,它通过将改变了的会话数据同步给集群中的其他所有节点实现会话复制。即这种实现会将所有会话的改变同步给集群中的每个节点,也是在集群环境中用的最多的一种实现方式。

缺陷:

这种会话管理只适合小规模(如3-5)的集群环境中。

当tomcat非正常关闭时会话数据会丢失,如断电。


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

  channelSendOptions="8">

4、BackupManager:

用于tomcat集群的会话管理器,与DeltaManager:不同的是,某节点会话的改变只会同步给集群中的

另一个随机节点而非所有节点。但是如果

缺陷:

这种会话管理只适合中等规模(如5-10)的集群环境中。

当tomcat非正常关闭时会话数据会丢失,如断电。


十、LB(Cluster Balance 负载均衡集群)总结:


1、4层LB:

(1)、lvs

(2)、haproxy(tcp)

2、7层LB:

(1)、apache(mod_jk,mod_proxy):ajp

(2)、apache(mod_proxy),haproxy,nginx:http


十一、构建DeltaManager集群步骤(即会话复制集群,这种集群只适用于小规模的集群环境中):


1、在各节点的server.xml的engine或host容器中,添加如下内容:

注意: tomcat官方站点(http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html)有配置文件

        <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>

(注意修改MemberShip组件中的多播地址address="228.0.0.4",

  建议修改Receiver中的address为本机能够传递心跳信息的地址)

2、在各节点为使用组播地址添加组播路由(windows无需此操作),格式:

route add -net MCAST_ADDRESS netmask 255.255.255.255 dev eth0

如:route add -net 228.0.0.4 netmask 255.255.255.255 dev eth0

3、在相应应用程序的web.xml中添加<distributable/> 或者添加到tomcat的web.xml中。

4、如果两个tomcat在同一台机器上,Receiver 要使用不同的端口号。


十二、Session服务器Memcached-Session-Manager:


参考文件:

https://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration


http://sourceforge.net/

http://www.slideshare.net/

https://zh-cn.wordpress.com/

https://code.google.com/

https://github.com/


十三、JVM管理的内存段可分为两类:线程共享内存和线程私有内存:

1、线程共享内存:

(1)java方法区:存储jvm加载的class、常量、静态变量、即时编译器编译后的代码等。

(2)java堆内存=新生代空间+老年代空间:堆内存存储java的所有对象实例、数组等。

 

2、线程私有内存:

(1)程序计数寄存器:每个线程都有自己的计数寄存器,存储当前线程执行字节码的地址。

(2)jvm栈:jvm会为每个运行线程分配一个栈区,线程调用方法时和方法返回时会进行入栈和出栈操作。

(3)本地方法栈区:与jvm栈类似,只不过此区域是为调用本地方法服务。


十四、JVM进程内部内存组织结构,见下图:

tomcat--高级_tomcat_04

1、定义“堆内存”空间边界

    -Xms:堆内存空间的初始值

    -Xmx:堆内存空间的最大值

2、定义“堆内存”空间内部内存的情况

    -XX:NewSize:堆内存空间新生代的初始值

    -XX:MaxNewSize:堆内存空间新生代的最大值

3、定义持久代空间的值

    -XX:PermSize:持久代空间的初始值

    -XX:MaxPermSize:持久代空间的最大值

备注:堆内存=新生代空间+老年代空间,JVM虚拟机内存参数调整如上1 、2、 3。

以上6个参数在linux环境下catalina.sh中的配置如下:

export JAVA_OPTS='-Xmx1024m -Xms512m -XX:NewSize=300m -XX:MaxNewSize=800m -XX:PermSize=64M -XX:MaxPermSize=128m'


十五、Java性能查看工具:

jconsole,jprofiler