nginx +tomcat 负载均衡集群的实现
tomcat  session server集群
tomcat session  cluster及jvm参数调整

一、nginx+tomcat 实现负载均衡群集

wget -c http://nginx.org/download/nginx-1.12.0.tar.gz 

tar xf nginx-1.12.0.tar.gz -C /usr/local/

cd /usr/local/

mv nginx-1.12.0 nginx

useradd www

yum install openssl gcc gcc-c++ openssl-devel pcre pcre-devel -y

./configure --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --prefix=/usr/local/nginx

make && make install

/usr/local/nginx/sbin/nginx -t

/usr/local/nginx/sbin/nginx

vi /usr/local/nginx/conf/nginx.conf

编辑配置文件,实现nginx+tomcat负载均衡如下

upstream tomcat{

        server 172.16.100.7:8080;

        server 172.16.100.8:8080;

    }

    server {

        listen       80;

        server_name  localhost;

        location / {

            proxy_pass http://tomcat;

            #root   html;

            #index  index.html index.htm;

        }

    }


二、tomcat session server (基于memcache来实现tomcat session保持)


环境描述:

               tomcat1:172.16.100.7(tomcatA.magedu.com),

               tomcat2:172.16.100.8(tomcatB.magedu.com)

               memcached1:172.16.100.9 

               memcached2:  172.16.100.10

               nginx负载均衡节点:172.16.100.6


下载jar文件

下载地址 :memcached-session-manager项目地址,http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/

jar文件至各tomcat节点的tomcat安装目录下的lib目录中,其中的${version}要换成你所需要的版本号,tc${6,7,8}要换成与tomcat版本相同的版本号。

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


分别在两个tomcat上的某host上定义一个用于测试的context容器,并在其中创建一个会话管理器,如下所示:


           <Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">

              <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"

                memcachedNodes="n1:172.16.100.9:11211,n2:172.16.100.10:11211"

                failoverNodes="n1"

                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"

                transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"

              />

             </Context>

说明:path 定义浏览器访问路径,docBase 定义应用程目录,nodes 为memcached 服务器地址,failoverNodes 定义备份session server,如果上文主为n2,当n2失败时,启动n1,


分别为两个context提供测试页面:

tomcatA:

# mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}

# vim /usr/local/tomcat/webapps/test/index.jsp

添加如下内容:

<%@ page language="java" %>

<html>

  <head><title>TomcatA</title></head>

  <body>

    <h1><font color="red">TomcatA.magedu.com</font></h1>

    <table align="centre" border="1">

      <tr>

        <td>Session ID</td>

    <% session.setAttribute("magedu.com","magedu.com"); %>

        <td><%= session.getId() %></td>

      </tr>

      <tr>

        <td>Created on</td>

        <td><%= session.getCreationTime() %></td>

     </tr>

    </table>

  </body>

</html>


tomcatB:

# mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}

# vim /usr/local/tomcat/webapps/test/index.jsp

添加如下内容:

<%@ page language="java" %>

<html>

  <head><title>TomcatB</title></head>

  <body>

    <h1><font color="blue">TomcatB.magedu.com</font></h1>

    <table align="centre" border="1">

      <tr>

        <td>Session ID</td>

    <% session.setAttribute("magedu.com","magedu.com"); %>

        <td><%= session.getId() %></td>

      </tr>

      <tr>

        <td>Created on</td>

        <td><%= session.getCreationTime() %></td>

     </tr>

    </table>

  </body>

</html>



在172.16.100.6上配置反向代理的负载均衡内容,类似如下所示:

upstream tomcat{

        server 172.16.100.7:8080;

        server 172.16.100.8:8080;

    }

    server {

        listen       80;

        server_name  localhost;

        location / {

            proxy_pass http://tomcat;

            #root   html;

            #index  index.html index.htm;

        }

    }


测试结果,在浏览器中访问http://172.16.100.6/test,结果如下所示,其session ID在负载均衡环境中保持不变。

TomcatA.magedu.com

Session ID4DD0340CE6294FF2BBE802CD4CD039EC-n2

Created on1399890838103


TomcatB.magedu.com

Session ID4DD0340CE6294FF2BBE802CD4CD039EC-n2

Created on1399890838103



三、tomcat session cluster (Tomcat基于内存复制的集群来实现session保持)

    会话管理器:

                标准会话管理器

                持久会话管理器

                群集会话管理器:多播方式传递自己的心跳信息,如 tomcatA把自己的session信息以多播的方式发送给其他tomcat主机,从而实现所有tomcat主机的会话信息完全一致;这样tomcatA、B、C节点同步会话信息时会占用大量带宽资源,不适应节点多的架构。

     修改server.xml文件,定义在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"           #节点服务器ip地址,最好设为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>

    

以上内容定义在Engine容器中,则表示对所有主机均启动用集群功能。如果定义在某Host中,则表示仅对此主机启用集群功能。此外,需要注意的是,Receiver中的address="auto"一项的值最好改为当前主机集群服务所对应的网络接口的IP地址。


如果tomcat启动报错中提示,找不到广播地址等信息,添加如下命令:

route add -net 228.0.0.4 netmask 255.255.255.255 dev eth0  

         修改web.xml文件,在webapp中(倒是第二行)添加 <distributable\> ,如果tomcat/webapps/test/WEB-INF/中没有web.xml ,需要从tomcat目录拷贝一份过去。    


  总结:构建DeltaManager集群步骤:

  1、在各节点的server.xml的engine或host容器添加如上内容;注意修改MemberShip组件中的多播地址address="228.0.0.4",建议修改Receiver中的address为本机能够传递心跳信息的地址;

  2、在各节点为使用组播地址添加组播路由,格式: route add -net $MCAST_ADDRESS netmask 255.255.255.255 dev eth0

  3、在相应应用程序的web.xml中添加<distributable\>; 

 此外,所有启用集群功能的web应用程序,其web.xml中都须添加<distributable/>才能实现集群功能。如果某web应用程序没有自己的web.xml,也可以通过复制默认的web.xml至其WEB-INF目录中实现。


四、tomcat server及jvm参数调整

    Tomcat脚本:

        startup脚本:

        #!/bin/sh

        # Tomcat init script for Linux.

        #

        # chkconfig: 2345 96 14

        # description: The Apache Tomcat servlet/JSP container.

        # JAVA_OPTS='-Xms64m -Xmx128m'

        JAVA_HOME=/usr/java/latest

        CATALINA_HOME=/usr/local/tomcat

        export JAVA_HOME CATALINA_HOME

        

        case $1 in

        start)

          exec $CATALINA_HOME/bin/catalina.sh start ;;

        stop)

          exec $CATALINA_HOME/bin/catalina.sh stop;;

        restart)

          $CATALINA_HOME/bin/catalina.sh stop

          sleep 2

          exec $CATALINA_HOME/bin/catalina.sh start ;;

        configtest)

          exec $CATALINA_HOME/bin/catalina.sh configtest ;;

        *)

          exec $CATALINA_HOME/bin/catalina.sh * ;;

        esac

        

    2、tomcat参数调优

    

        基于连接器提高Tomcat6性能的方法:

        1) 设置tcpNoDelay属性值为“true”;

        2) 通过maxKeepAliveRequest属性调整允许keep-alive功能的请求的最大数目,值为1时表示禁用;

        3) 调整socketBuffer属性的值以改变套接字缓冲的大小;

        4) 将enableLookups设置为false以禁用DNS反解;

        5) Tomcat是一个多线程的Servlet容器,使用线程池能对服务器性能带去很大影响;这主要通过maxThreads、maxSpareThreads和minSpareThreads来定义;

        6) 通过JAVA_OPTS,如-Xms和-Xmx设定JVM相关的参数以定义其使用内存的能力;