Nginx的tomcat集群与负载均衡配置

Posted 奔跑在梦想的道路上

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx的tomcat集群与负载均衡配置相关的知识,希望对你有一定的参考价值。

  一.什么是Nginx?

  nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

  Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用Nginx的网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

  二.为什么要用Nginx?

  提及Nginx,我们就需要了解下web应用服务器。在此,我们暂且以tomcat这款应用服务器为例来介绍。

  Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。由于Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

  Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。

  一般来说,用单机tomcat搭建的网站,在比较理想的状态下能够承受的并发访问量在150到200左右。按照并发访问量占总用户数量的5%到10%这样计算,单点tomcat网站的用户人数在1500到4000左右。对于一个为全国范围提供服务的网站显然是不够用的。

  在互联网飞速发展的今天,大用户量高并发已经成为互联网的主体.怎样能让一个网站能够承载几万个或几十万个用户的持续访问呢?这是一些中小网站急需解决的问题。

  为了解决这个问题,我们引入了负载均衡方法。负载均衡就是一个web服务器解决不了的问题可以通过多个web服务器来平均分担压力来解决,并发过来的请求被平均分配到多个后台web服务器来处理,这样压力就被分解开来。

  目前,负载均衡服务器主要分为两种,一种是通过硬件实现的负载均衡服务器,简称硬负载,例如f5;另一种是通过软件来实现的负载均衡,简称软负载,例如apache和nginx。硬负载和软负载相比,前者作用的网络层次比较多,可以作用到socket接口的数据链路层,并且对发出的请求进行分组转发,但是价格成本也随之较贵;而软负载作用的层次在http协议层之上,可以对http请求进行分组转发,并且由于是开源的,所以几乎是0成本,当前,阿里巴巴,京东等电商网站使用的也是Nginx服务器。

  我们接下来以一副示意图演示Nginx对tomcat的负载均衡配置:

  三.tomcat如何配置首个启动工程?

  在讲述Nginx负载均衡之前,我们先熟悉tomcat的配置。

  以win7系统为例,我们平时在电脑上开启tomcat应用后,通过浏览器访问,会访问到tomcat的系统默认首页。那么,如何修改tomcat的首个启动工程呢?

  以tomcat7为例,我们将一个名称为Demo1的java web项目导出为一个war文件,然后放在tomcat的webapps文件夹下,接着打开tomcat的conf文件夹下的server.xml文件,在<Host></Host>中加入

  <Context docBase="E:\\nginx\\tomcatA\\webapps\\Demo1" path="" reloadable="true" crossContext="true"/>

  然后重启tomcat,并在浏览器地址栏里输入http://localhost:8080,这时就会发现tomcat的默认首个启动工程变为Demo1。

  四.如何在同一个tomcat上配置多个虚拟主机?

  接下来,我们再看如何在一台服务器上设置多个域名,从而使得用户访问多个域名时,可以分别指向同一个tomcat应用服务器中配置的不同web工程。 

 首先,我们按照C:\\Windows\\System32\\drivers\\etc路径,打开该路径下的hosts文件,在里面配置下域名映射信息,如下: 
 
    127.0.0.1 www.baidudu.com
    127.0.0.1 www.taobaobao.com

  接着,我们另建两个java web项目,分别是Demo1和Demo2,然后再打开tomcat中的server.xml文件,在里面配置两个服务器主机信息,如下所示:

  <Host name="www.baidudu.com" appBase="webapps" autoDeploy="true" unpackWARs="true">
    <Context docBase="E:\\nginx\\tomcatA\\webapps\\Demo2" path="" reloadable="true" crossContext="true"/>
  </Host>    
  <Host name="www.taobaobao.com" appBase="webapps" autoDeploy="true" unpackWARs="true">
    <Context docBase="E:\\nginx\\tomcatA\\webapps\\Demo3" path="" reloadable="true" crossContext="true"/>
  </Host>

  配置完毕后,我们再重启tomcat,分别访问新配置的两个域名,发现它们会各自指向相应的web工程,从而实现了用一个tomcat配置多个虚拟主机。

  五.如何通过Nginx实现tomcat集群配置与负载均衡?  

  我们接下来看通过Nginx对多个tomcat进行集群配置。在这里,我暂且在一台电脑上用两个tomcat做下演示,同时将这两个tomcat分别命名为tomcatA和tomcatB。为了避免同一台电脑上开启多个tomcat引起端口冲突,我将tomcatA的http访问端口配置为8081,将tomcatB的http访问端口配置为8082,为了显示不同tomcat的访问区别,我暂且让tomcatA的默认首个启动工程为Demo1,让tomcatB的默认首个启动工程为Demo3。
  接着,我们双击ningx中的nginx.exe文件,从而启动nginx服务。当然,我们这里还需要对nginx中的配置文件进行一番配置,所以,如果nginx处于开启状态,则暂且在DOS窗口中关闭nginx服务。如图所示:

  接下来,我们打开nginx中的conf文件夹下的nginx.conf文件,我们在里面加入要配置的tomcat集群,同时,考虑到不同的服务器性能差别,可以配置相应的权重,从而实现服务器的负载均衡。如下图所示:

  

  上图中,标注红框的部分是关键配置,然后,我们在浏览器的地址栏中输入localhost,会发现tomcatA和tomcatB的所承担的访问任务比重约为5:1,从而实现了nginx对tomcat的负载均衡配置。

  六.如何处理Nginx负载均衡中的session会话信息丢失问题?  

  我们在通过nginx完成了对tomcat的集群与负载均衡配置后,还面临着一个关键问题,那就是如何解决session会话信息的共享问题。解决方法也很简单,需要两个步骤:

  步骤一:在每个tomcat的server.xml中找到标签:

<Engine name="Catalina" defaultHost="localhost">
#....
#....
#....
</Engine>

  在上面的<Engine></Engine>标签中加入下述代码,注意不要做任何更改:

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

  步骤二:在web项目的web.xml文件中,添加节点<distributable/>就可以了,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <distributable/>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

  到此,我们就解决了Nginx在tomcat集群配置中的session共享问题。这是基于tomcat自身的广播机制完成,虽然在功能上实现了session共享,但是运行效率相对较低。

  为此,我们再介绍一种企业级解决方案,那就是引入redis缓存完成session共享。

  那么,什么是redis呢?为此,我们要对NoSql有所了解。NoSql叫非关系型数据库,它的全名Not only sql,它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。它是为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案。

  NoSql可以有多种分类,如根据键值对(Key-Value)存储数据的数据库(如Redis),列存储型数据库(如Hbase),文档型数据库(如MongoDB),图形(Graph)数据库等。我们在这里用到的Redis就是NoSql数据库中的一种。Redis可以将数据储存在缓存中,极大地提高了访问数据的效率,还可以根据需要对数据进行持久化存储。

  Redis中可以储存5种类型的数据,分别是:  

1 String
2 hash
3 list
4 set
5 zset

  言归正传,我们继续介绍运用Redis实现session共享。

  首先,我们可以根据自己所用电脑的操作系统下载Redis文件,如下图所示:

  我们以Windows系统为例,上面分别对应32位和64位的win7操作系统,我们选择对应的压缩文件,解压到电脑中的一个位置,如下图所示:

  在上图中,我们可以对redis的配置做下修改,如设置数据持久化策略,配置端口号等,为了方便启动redis服务器,我们还可以写个批处理文件,通过双击该批处理文件即可启动redis。上图中的“启动redis服务器.bat”文件内容如下:

C:
cd C:\\Users\\Administrator\\Desktop\\work\\redis
redis-server redis.windows.conf

  接下来,为了便于更好地模拟nginx集群配置tomcat时解决session共享的问题,我们先下载好nginx和两个tomcat,如下图所示:

  然后,我们在每个tomcat中的server.xml里,删除原先通过tomcat广播机制配置的代码块,如下图所示:

  然后,我们继续在server.xml中,找到<Context  />标签,将其改成<Context></Context>,根据需要,在该标签中加入下面的信息

<Context docBase="E:\\nginx\\tomcatB\\webapps\\Demo" path="" reloadable="true" crossContext="true">
        <!--redis配置session共享-->
         <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
            <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
                host="127.0.0.1"     
                port="6379"     
                maxInactiveInterval="600000"
                <!--
                database="0"         #optional: defaults to "0"
                sessionPersistPolicies="PERSIST_POLICY_1,PERSIST_POLICY_2,.."     #optional 
                sentinelMaster="SentinelMasterName"         #optional 
                sentinels="sentinel-host-1:port,sentinel-host-2:port,.." />     # optional
                -->
         />         
</Context>

  我们要在做集群配置的tomcat的server.xml中均做如上配置,同时确保在web项目的web.xml中添加上<distributable/>标签

  接着,我们把三个jar包放入每个tomcat根目录下的lib文件中,三个jar包如下图所示(您可以在网上download,如果找不到请给我留言,并留下您的邮箱,我会发给您):

  至此,我们就运用redis技术做好了nginx集群配置tomcat中面临的session共享问题。

  最后,我们依次开启tomcat,nginx,以及redis,就会发现session已经实现了共享。

以上是关于Nginx的tomcat集群与负载均衡配置的主要内容,如果未能解决你的问题,请参考以下文章

图文详解 配置Nginx+Tomcat负载均衡动静分离集群

Nginx+Tomcat负载均衡集群

图文解说:Nginx+tomcat配置集群负载均衡

Nginx + Tomcat 配置负载均衡集群

Nginx + Tomcat 配置负载均衡集群

Nginx + Tomcat 配置负载均衡集群简单实例