DevOps

Tomcat LB cluster实战详解

2018-04-24  本文已影响1人  4e8ea348373f

一,会话保持

1.session sticky source ip,cookie
2.session cluster 利用多播集群内互相传递session
3.session server 高性能的kv server memcached,redis 使用redis

二,准备环境

1.准备3台contos7的虚拟机 分别为node[1-3],node[1-2]提供Tomcat服务,node3提供集群调度
2.关闭防火和selinux
3.同步时钟
4.配置好java环境
5.在node[1-2]部署好tomcat

三,配置集群

1.在node1和node2的tomcat的server.xml中添加一个Host

<Host name="www.node1.com" appBase="/data/webapps" autoDeploy="true">
       <Context path="" docBase="ROOT">
       </Context>
     </Host>

2.为node1,node2提供不同的应用
3.在node3上安装并配置nginx

#nginx安装不说了
#配置文件
在http配置段中添加,最好在server段的上方添加
upstream tcsrvs {
        server www.node1.com:8080;
        server www.node2.com:8080;
        }
location ~*\.(jsp|do)$ {
                proxy_pass http://tcsrvs;
        }

在server段中修改location,指明只有jsp,do等后端内容时才代理到upstream server
启动nginx,测试即可

四,会话绑定

在upstream中加入ip_hash;即可
upstream tcsrvs {
        ip_hash;
        server www.node1.com:8080;
        server www.node2.com:8080;
        }

PS:LNAMT nginx做负载均衡器,在每台tomcat上配置httpd反向代理用户请求

五,使用httpd做负载均衡器

1.方案一

(1)apache: mod_proxy,mod_proxy_http mod_proxy_balancer
(2)tomcat http connector

2.方案二

(1)apache: mod_proxy,mod_proxy_ajp mod_proxy_balancer
(2)tomcat ajp connector

3.方案三 (不怎么使用了)

(1)apache: mod_jk
(2)tomcat ajp connector

六,配置httpd

#关闭中心主机
[root@node3 ~]# vim /etc/httpd/conf/httpd.conf
注释掉DocumentRoot "/var/www/html"

#修改每台主机的server.xml文件,添加jvmRoute 唯一标识,不是必须
<Engine name="Catalina" defaultHost="www.node1.com" jvmRoute="TomcatA">

准备特定的index.js文件
演示效果,在TomcatA上某context中(如/test),提供如下页面
<%@ 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上某context中(如/test),提供如下页面
<%@ 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>

在node3 httpd然后自定义一个配置文件(虚拟主机)
[root@node3 conf.d]# pwd
/etc/httpd/conf.d
[root@node3 conf.d]# vim vhosts.conf
<proxy balancer://lbcluster1>
   BalancerMember http://192.168.66.129:8080 loadfactor=10 route=TomcatA
   BalancerMember http://192.168.66.130:8080 loadfactor=10 route=TomcatB
</proxy>
<VirtualHost *:80>
   ServerName www.node1.com
   ProxyVia On
   ProxyRequests Off
   ProxyPreserveHost On
   <Proxy *>
     Require all granted
   </Proxy>
   ProxyPass / balancer://lbcluster1/
   ProxyPassReverse / balancer://lbcluster1/
   <Location />
     Require all granted
   </Location>
</VirtualHost>

问题1 httpd -t 警告
[root@node3 conf.d]# httpd -t
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.66.131. Set the 'ServerName' directive globally to suppress this message
解决方法
添加ServerName localhost:80

PS:刷新是发现用户seesion变化了,这里使用stickysession解决 session绑定

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://lbcluster1>
   BalancerMember http://192.168.66.129:8080 loadfactor=10 route=TomcatA
   BalancerMember http://192.168.66.130:8080 loadfactor=10 route=TomcatB
   ProxySet stickysession=ROUTEID
</proxy>

配置请参考httpd mod_proxy_balancer模块官方文档

七,httpd ajp模式

#Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://lbcluster1>
   BalancerMember ajp://192.168.66.129:8009 loadfactor=10 route=TomcatA
   BalancerMember ajp://192.168.66.130:8009 loadfactor=10 route=TomcatB
  #ProxySet stickysession=ROUTEID
</proxy>
<VirtualHost *:80>
   ProxyVia On
   ProxyRequests Off
   ProxyPreserveHost On
   <Proxy *>
     Require all granted
   </Proxy>
   ProxyPass / balancer://lbcluster1/
   ProxyPassReverse / balancer://lbcluster1/
   <Location />
     Require all granted
   </Location>
#会话绑定只需要开启ProxySet stickysession=ROUTEID
#开启管理模块
用于mod_proxy状态信息的输出
<Location /balancer-manager>
  SetHandler balancer-manager
  Proxypass !
  Order Deny,Allow
  Allow from all
</Location>

八,session集群

标准会话管理器(StandardManager):

<Manager className="org.apache.catalina.session.StandardManager"
maxInactiveInterval="7200"/>
默认保存于$CATALINA_HOME/work/Catalina/<hostname>/<webapp-name>/下的SESSIONS.ser文件中。
maxActiveSessions:最多允许的活动会话数量,默认为-1,表示不限制;
maxInactiveInterval:非活动的会话超时时长,默认为60s;
pathname:会话文件的保存目录;

持久会话管理器(PersistentManager):

将会话数据保存至持久存储中,并且能在服务器意外中止后重新启动时重新加载这些会话信息。持久会话管理器支持将会话保存至文件存储(FileStore)或JDBC存储(JDBCStore)中。
保存至文件中的示例:
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true">
<Store className="org.apache.catalina.session.FileStore"
directory="/data/tomcat-sessions"/>
</Manager>
每个用户的会话会被保存至directory指定的目录中的文件中,文件名为<session id>.session,并通过后台线程每隔一段时间(checkInterval参数定义,默认为60秒)检查一次超时会话。
保存至JDBCStore中的示例:
<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=jb;password=pw"/>
</Manager>

九,会话复制配置

     <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.ClusterSessionListener"/>
        </Cluster>

为需要使用session cluster的webapps开启session distribution的功能:
WEB-INF/web.xml中添加
<distributable/>
配置请参考tomcat官方文档

十,session服务器

参考实现
百度 tomcat redis session
Tomcat8 + Redis实现session集中管理
使用Redis存储Nginx+Tomcat负载均衡集群的Session
搭建Tomcat集群&通过Redis缓存共享session的一种流行方案

上一篇 下一篇

猜你喜欢

热点阅读