首页 > 其他分享 >Tomcat原理详解和各种集群的实现

Tomcat原理详解和各种集群的实现

时间:2023-09-20 14:03:51浏览次数:46  
标签:catalina Java Tomcat tomcat 详解 集群 TomcatA apache root


转载, 原始出处 : http://harisxiong.blog.51cto.com/7513022/1304746



注意:本篇博文涉及的知识内容如下,实验中所用的系统环境为RHEL6.4。

1.Java基础知识讲解

2.Tomcat的安装和实现

3.通过apache的mod_proxy模块代理并实现Tomcat负载均衡

4.基于Tomcat集群的网上商城的实现

------------------------------------------------------------------------------------------

1.Java基础知识讲解

1.1.Java相关的体系结构

1.Java程序设计语言

2.Java class 文件格式

3.Java 应用编程接口

4.Java 虚拟机

1.2.Java运行环境

用Java语言编译源代码,把它编译成Java Class文件,然后在Java VM中运行class文件;当编写程序时,通过调用类(Java API)中的方法来访问系统资源,而当程序运行时,它通过调用class文件中实现了Java API的方法也满足程序的Java API调用。Java VM和Java API一起组成了一个“平台”,所有Java程序都在其上编译和运行,因此,它们有时也被称作Java运行时环境。

相关实现模型如下:

Tomcat原理详解和各种集群的实现_开发工具

1.3.JVM(虚拟机)运行数据区域

Tomcat原理详解和各种集群的实现_开发工具_02

1.4.相关术语概念

1.JVM : Java虚拟机 主要包含类加载器和相关的执行引擎

2.JDK : Java开发工具 主要包括Java运行环境,和javac编辑器及相关的API

3.Java SE : 包含JDK和一些核心的JAVA API

4.Java EE : 由Java SE 和一些Java企业级的API组成

1.5.web容器(Tomcat)

当JSP应用程序第一次调用之后,JSP会被编译成一个servlet类,后续的操作直接使用此类,从而避免了每次调用的都要重新分析和编译。因此,类似servlet,JSP的执行需要在container中完成JSP的container跟servlet的container基本相同。但在JSP执行之前,需要一些额外的步骤如与servlet代码建立会话等。Tomcat包含了一个叫做Catalina的Servlet container(执行servlet和编译过的JSP)和一个JSP编译器(Jasper)。

事实上,一个包含了JSP编译器和Servlet容器的应用程序组合通过被称作Web容器。

 

2.Tomcat的安装和实现

2.1.JDK的安装

目前开源的JDK有ApacheHarmony, OpenJDK, SunJDK等。下载链接:

http://www.oracle.com/technetwork/java/javase/downloads/index.html


[root@TomcatA ~]           # rpm -ivh jdk-7u9-linux-x64.rpm          


           [root@TomcatA ~]           # ll /usr/java/          


           total 4          


           lrwxrwxrwx  1 root root   16 Oct 3 19:52 default ->            /usr/java/latest          


           drwxr-xr-x 10 root root 4096 Oct 3 19:52 jdk1.7.0_09          


           lrwxrwxrwx  1 root root   21 Oct 3 19:52 latest ->           /usr/java/jdk1           .7.0_09          


           [root@TomcatA ~]           # vim /etc/profile.d/java.sh          


           export            JAVA_HOME=           /usr/java/latest          


           export            PATH=$JAVA_HOME           /bin           :$PATH          


           [root@TomcatA ~]           # . /etc/profile.d/java.sh          


           [root@TomcatA ~]           # java -version          


           java version            "1.7.0_09"          


           Java(TM) SE Runtime Environment (build 1.7.0_09-b05)          


           Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)          


           [root@TomcatA ~]           #



2.2.Tomcat安装(JAVA程序)

官方网站: http://tomcat.apache.org/

 

[root@TomcatA ~]           # tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/          


           [root@TomcatA ~]           # cd /usr/local/          


           [root@TomcatA ~]           # ln -sv apache-tomcat-7.0.42 tomcat          


           `tomcat' -> `apache-tomcat-7.0.42          


           [root@TomcatA ~]           # vim /etc/profile.d/tomcat.sh          


           export            CATALINA_HOME=           /usr/local/tomcat          


           exportPATH=$CATALINA_HOME           /bin           :$PATH                


           [root@TomcatA ~]           # catalina.sh --help     #显示相关的命令选项          


           [root@TomcatA ~]           # jps                    #显示当前系统运行的JVM程序



 

2.3.编辑启动服务脚本:

[root@TomcatA ~]# 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 -Xmx256m'                    #设置JAVA运行时的内容大小          


           JAVA_HOME=           /usr/java/latest          


           CATALINA_HOME=           /usr/local/tomcat          


           export            JAVA_HOME CATALINA_HOME          


           exec            $CATALINA_HOME           /bin/catalina           .sh $*



2.4.配置文件介绍:

Tomcat的配置文件默认存放在$CATALINA_HOME/conf目录中,主要有以下几个:

1.server.xml: Tomcat的主配置文件,Service, Connector, Engine, Realm, Valve,Hosts主组件的相关配置信息;

2.web.xml:遵循Servlet规范标准,用于配置servlet,并为所有的Web应用程序提供包括MIME映射等默认配置信息;

3.tomcat-user.xml:Realm认证时用到的相关角色、用户和密码等信息;Tomcat自带的manager默认情况下会用到此文件;在Tomcat中添加/删除用户,为用户指定角色等将通过编辑此文件实现;

4.catalina.policy:Java相关的安全策略配置文件,在系统资源级别上提供访问控制的能力;

5.catalina.properties:Tomcat内部package的定义及访问相关的控制,也包括对通过类装载器装载的内容的控制;Tomcat6在启动时会事先读取此文件的相关设置;

6.ogging.properties:Tomcat6通过自己内部实现的JAVA日志记录器来记录操作相关的日志,此文件即为日志记录器相关的配置信息,可以用来定义日志记录的组件级别以及日志文件的存在位置等;

7.context.xml:所有host的默认配置信息;

2.5.主配置文件/usr/local/tomcat/conf/server.xml中常用的组件介绍:

Server组件:使tomcat服务器启动一个实例

Service组件:关联一个引擎和此引擎相关的连接器

Connector组件:为引擎设置相关的连接器以接受客户端的访问请求

Engine组件:是servlet处理器的一个实例,即servlet引擎

Host组件:位于engine容器中用于接收请求并进行相应处理的主机或虚拟主机

Context组件:在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序

其余组建和详细参数信息请参考官方文档,在这里我就不再叙述。

2.6.应用程序目录的结构:

/WEB-INF/web.xml:包含当前webapp的deploy描述符,如所有的servlets和JSP等动态文件的详细信息,会话超时时间和数据源等;因此,其也通常用于定义当前webapp特有的资源;

/WEB-INF/classes: 包含所有服务器端类及当前应用程序相关的其它第三方类等;

/WEB-INF/lib: 包含JSP所用到的JAR文件;

2.7.简单测试:

我们将上述connector的端口由默认的8080修改为80,重启tomcat服务器并进行简单的访问测试

Tomcat原理详解和各种集群的实现_tomcat_03

 

3.通过apache的mod_proxy模块代理并实现Tomcat负载均衡

3.1.实验拓扑环境

Tomcat原理详解和各种集群的实现_开发工具_04

3.2.简单应用程序的部署

在这里我们使用默认的/usr/local/tomcat/webapps/目录直接部署虚拟目录实现,而不再使用单独的虚拟主机定义。配置简单实现如下:

TomcatA:

 

[root@TomcatA ~]           # cd /usr/local/tomcat/webapps/          


           [root@TomcatA webapps]           # mkdir -pv test/WEB-INF/{classes,lib}          


           [root@TomcatA webapps]           # vim test/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>



TomcatB:

主要配置同TomcatA相同,只需要设置不同的主页文件:

 

[root@TomcatA webapps]           # vim test/index.jsp


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



#配置完成之后,利用之前提供的脚本重启两台tomcat服务器。

Apache:利用mod_proxy模块实现负载均衡。

1.启动RHEL6.4上默认的httpd服务。

2.新添加配置文件如下:

 

[root@apache ~]           # vim /etc/httpd/conf.d/mod_proxy.conf          


           ProxyVia on            


           ProxyRequests Off                                   #关闭正向代理          


           ProxyPreserveHost Off          


           <Proxy balancer:           //xkun           >                             #定义代理的后端real server          


                      BalancerMemberajp:           //192           .168.21.1:8009 loadfactor=1          


                      BalancerMemberajp:           //192           .168.21.2:8009 loadfactor=1          


                      ProxySetlbmethod=byrequests          


           <           /Proxy           >          


           <Location            /xkun           >                                    #状态检测的实现          


                      SetHandler balancer-manager                 #调用处理模块          


                      Proxypass !                                 #不向后方代理          


                      Order allow,deny                            #定义访问权限          


                      Allow from all                              #建议在实际生产中做好访问控制          


           <           /Location           >          


           <Proxy *>                                           #相关反向代理的权限控制          


                      Order allow,deny          


                      Allow from all          


           <           /Proxy           >          


           ProxyPass  /  balancer:           //xkun/                      #设置代理路径的映射管理          


           ProxyPassReverse  /  balancer:           //xkun/          


           <Location  / >                                      #定义相关的访问控制策略          


                      Order allow,deny          


                      Allow from all          


           <           /Location           >



3.重启所有服务器进行访问测试

#注意:重启之前,最好编辑/etc/sysctl.conf文件打开ip_forward转发

# service httpd start

3.3.简单测试如下:

1.查看状态信息

Tomcat原理详解和各种集群的实现_tomcat_05

2.查看部署好的jsp程序

Tomcat原理详解和各种集群的实现_后端_06

3.4.实验总结:

1.通过上述实验我们实现了如何利用apache的mod_proxy模块实现了tomcat的负载均衡。

2.虽然本次实现了tomcat负载均衡但我们发现session无法得到保持。我将在一下叙述中进行实现

3.5.基于内存复制实现tomcat集群中的session共享

1.分别在TomcatA和TomcatB服务器的主配置文件上添加如下信息(只需修改各自的receiver):

# vim server.xml #添加在引擎容器中以实现所有虚拟主机的共享

 

 

<           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"            <!--注意修改地址为自己的网卡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.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           >




2.完成之后,还需要在应用程序部署目录中添加下配置文件并修改,实现两台tomcat的内存共享:

[root@TomcatA ~]           # cd /usr/local/tomcat/conf/          


           [root@TomcatA conf]           # cp -a web.xml ../webapps/test/WEB-INF/          


           # 修改web.xml文件在 web-app 容器中添加如下行:          


           <distributable />



3.同样在TomcatB上进行同样的配置,添加相同的配置文件。只是需要将地址修改为自己网卡地址,在上述代码中已给有提示。关于server.xml中添加集群相关的配置文件详解请参考官方文档。

4.同启重启后端的两台tomcat服务器,并进行访问测试结果如下:

Tomcat原理详解和各种集群的实现_tomcat_07

我们发现无论如何刷新,session id的信息都不会再改变。至此,我们完成了如何利用apache的mod_proxy模块实现tomcat服务器的负载均衡,同时我们也完成了tomcat内存共享集群的实现。下面我将通过一个网上购物商城实例来给大家做进一步的讲解和总结。

 

4.基于Tomcat集群的网上商城的实现

4.1.实验拓扑环境:

Tomcat原理详解和各种集群的实现_tomcat_08

4.2.shop应用程序的部署

注意:同样在这里我们使用默认的/usr/local/tomcat/webapps/目录直接部署虚拟目录实现。

下载开源网上购物商城程序包如下:shopxx-a5-Beta.zip

下载路径:

简单配置如下:

1.TomcatA:

 

[root@TomcatA ~]           # unzip shopxx-a5-Beta.zip          


           [root@TomcatA ~]           # cd shopxx-v3.0-Beta/          


           [root@TomcatA shopxx-v3.0-Beta]           # ls shopxx-3.0Beta/          


           admin          favicon.ico             install                 META-INF   robots.txt  upload          


           changelog.txt  index.jsp    license.html  resources shopxx.txt  WEB-INF          


           [root@TomcatA shopxx-v3.0-Beta]           # mv shopxx-3.0Beta /usr/local/tomcat/webapps/shop




2.MySQL: (安装方法我就不再叙述,可以参考之前的博客)

 

mysql> create database shopxx;          


           mysql> create user            'showuser'           @           '%'            identified by           'showpass'           ;          


           mysql> grant all on shopxx.* to            'showuser'           @           '%'           ;




 

3.Apache: (代理配置文件和上一个实现相同,这里就不再给出)

先注释BalancerMemberajp://192.168.21.2:8009 loadfactor=1

4.然后访问:http://172.16.21.100/shop 根据提示进行安装:直至出现如下界面:

Tomcat原理详解和各种集群的实现_tomcat_09

5.TomcatB: 将TomcatA的关于shop/目录的配置复制到TomcatB中。

 

# scp -rp shop 192.168.21.2:/usr/local/tomcat/webapps/[email protected]




 

问题:在购物商城的实现过程中,我也遇见了session无法保持的情况。即同一用户再次登录时购物车的商品有可能为空。

解决方案:利用tomcat集群实现内存共享,这在上面的案例中也有介绍。

同样修改配置文件server.xml添加上述内容(在上面我已经做过详细的说明)。

同时修改配置文件#vim shop/WEB-INF/web.xml添加如下一行

<distributable />

同时启动tomcat服务器。

当端口启动时,再次访问站点主页进行测试http://172.16.21.100/shop

Tomcat原理详解和各种集群的实现_web.xml_10

注册用户并将商品加入购物车。多次执行退出登录操作。我们发现购物车的商品一直存在:

Tomcat原理详解和各种集群的实现_tomcat_11

无论我如何刷新,登录用户的购物车信息都会存在。实现了后端集群的信息共享。至此基于tomcat的集群的相关实现我已经写完了。如果大家有什么疑问欢迎和我交流。


注意:本次实验所用的系统环境为RHEL6.4,整个实验过程全部由笔者亲自实践。笔者将会在后续的博客中陆续更新:如何利用HAProxy代替apache实现反向代理并实现动静分离,并利用keepalived实现HAProxy的高可用。同时也会将HAProxy替换成Varnish实现相应的反向代理和缓存。通过对多种web架构的实现并进行相应的压力测试,比较各种架构的性能好坏。

 

 

本文出自 “Haris” 博客,请务必保留此出处http://harisxiong.blog.51cto.com/7513022/1304746

标签:catalina,Java,Tomcat,tomcat,详解,集群,TomcatA,apache,root
From: https://blog.51cto.com/u_16242566/7536823

相关文章

  • HttpServletRequest 方法详解
    request.setCharacterEncoding("utf-8");//设置request编码方式 request.getLocalAddr();//获取本地IP,即服务器IP request.getLocalName();//获取本地名称,即服务器名称 request.getLocalPort();//获取本地端口号,即Tomcat端口号 request.getLocale();//用户的语言环境 req......
  • HTTP响应头信息和请求头信息详解
    web性能测试中有一个web资源分析,web资源是从服务器入手对web服务器的性能进行分析。所以了解一下以下信息是很有必要的哦。一:响应头信息HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616。HTTP协议采用了请求/响......
  • Tomcat集群配置学习篇-----分布式应用
    Tomcat集群配置学习篇-----分布式应用现目前基于javaWeb开发的应用系统已经比比皆是,尤其是电子商务网站,要想网站发展壮大,那么必然就得能够承受住庞大的网站访问量;大家知道如果服务器访问量过大,就会出现服应用务器崩溃的情况,这个时候怎么办,难道就只能去重启服务器吗?好,如果是一般的小......
  • tar 解压缩命令详解
    解压操作:#tar-zxvf/usr/local/test.tar.gztar解压缩命令详解-c:建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时......
  • 最全详解Android设备UDID还是唯一ID?
    这篇文章主要介绍了Android设备UDID还是唯一ID?我觉得挺不错的,现在分享给大家,也给大家做个参考。我想为我的Android应用程序生成android设备唯一ID,以根据用户设备udid创建收藏夹.所有设备都有唯一的ID.importandroid.provider.Settings.Secure;privateStringandroid_id=Se......
  • 苹果app开发流程详解
    苹果app开发流程详解 苹果AppStore上传应用流程详解,在向AppStore提交应用之前,开发者首先要成为苹果iOS开发者项目的成员,每年向苹果缴纳99美元或199美元的费用(具体申请方法后期更新)。免688开发IOS应用,根据apple的规定,不支付688,可以开发IOS应用,但是不支持提交审核,推送,支付和apple登......
  • 图注意网络(GAT)的可视化实现详解
    前言 能够可视化的查看对于理解图神经网络(gnn)越来越重要,所以这篇文章将介绍传统GNN层的实现,然后展示ICLR论文“图注意力网络”中对传统GNN层的改进。本文转载自DeepHubIMBA作者:DavidWiner仅用于学术分享,若侵权请联系删除欢迎关注公众号CV技术指南,专注于计算机视觉的技术......
  • iOS app上架app store流程详解
    前提条件在有效期内的苹果开发者账号(类型为个人或者公司账号)。还有一种情况,就是你的AppleID被添加到公司开发者账号团队里面,这样也是可以的,但是需要叫管理员给你开通相应的账号权限,如下截图:这里可能有些同学会问,苹果开发者账号是什么?如何申请?那么可以看看我的上一篇文章:iOS苹果开......
  • Hadoop集群的NameNode的备份
    Hadoop集群中,NameNode节点存储着HDFS上所有文件和目录的元数据信息如果NameNode挂了,也就意味着整个Hadoop集群也就完了所以,NameNode节点的备份很重要,可以从以下2个方面来备份NameNode节点1.在hdfs-site.xml中,配置多个name的dir到不同的磁盘分区上:<property>   <name>dfs.name.......
  • HFile详解-基于HBase0.90.5
    1.HFile详解HFile文件分为以下六大部分 序号名称描述1数据块由多个block(块)组成,每个块的格式为:[块头]+[key长]+[value长]+[key]+[value]。2元数据块元数据是key-value类型的值,但元数据快只保存元数据的value值,元数据的key值保存在第五项(元数据索引块)中。该块由多个元数......