• Nginx集群配置与redis的session共享策略


      一.什么是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: ginx omcatAwebappsDemo1" path="" reloadable="true" crossContext="true"/>

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

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

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

     首先,我们按照C:WindowsSystem32driversetc路径,打开该路径下的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:
    ginx	omcatAwebappsDemo2" path="" reloadable="true" crossContext="true"/>
      </Host>    
      <Host name="www.taobaobao.com" appBase="webapps" autoDeploy="true" unpackWARs="true">
        <Context docBase="E:
    ginx	omcatAwebappsDemo3" 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:UsersAdministratorDesktopwork
    edis
    redis-server redis.windows.conf

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

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

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

    <Context docBase="E:
    ginx	omcatBwebappsDemo" 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已经实现了共享。

  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/lizhangyong/p/8370638.html
Copyright © 2020-2023  润新知