tomcat(九)http实现tomcat负载均衡

By | 2019年 11月 23日

实验:httpd 负载均衡 tomcat

使用httpd -M 可以看到proxy_balancer_module,用它来实现负载均衡。

方式依赖模块
http负载均衡mod_proxy
mod_proxy_http
mod_proxy_balancer
ajp负载均衡mod_proxy
mod_proxy_ajp
mod_proxy_balancer

准备另一个主机:192.168.99.124,做httpd主机

  • httpd主机上
  1. 安装httpd
yum install httpd -y
  1. 修改配置,注释这一行
vim /etc/httpd/conf/httpd.conf 
#DocumentRoot "/var/www/html"
  1. 添加配置
vim /etc/httpd/conf.d/vhost.conf
<VirtualHost *:80>
 ServerName             webserver.com
 ProxyRequests          Off
 ProxyVia               On
 ProxyPreserveHost      On
 ProxyPass      /               balancer://lbtomcats/
 ProxyPassReverse   /           balancer://lbtomcats/
</VirtualHost>

<Proxy balancer://lbtomcats>
 BalancerMember http://node1.com:8080 loadfactor=1
 BalancerMember http://node2.com:8080 loadfactor=2
</Proxy>
  1. 检查配置语法
httpd -t
  1. 启动httpd服务
systemctl start httpd
  1. 添加域名解析
vim /etc/hosts
192.168.99.122 node1.com
192.168.99.123 node2.com
192.168.99.124 webserver.com
  1. 测试
curl webserver.com/index.jsp

配置 httpd 实现 session 粘性

  1. 修改配置
vim /etc/httpd/conf.d/vhost.conf
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

<VirtualHost *:80>
 ServerName             webserver.com
 ProxyRequests          Off
 ProxyVia               On
 ProxyPreserveHost      On
 ProxyPass      /               balancer://lbtomcats/
 ProxyPassReverse   /           balancer://lbtomcats/
</VirtualHost>

<Proxy balancer://lbtomcats>
 BalancerMember http://node1.com:8080 loadfactor=1 route=Tomcat1
 BalancerMember http://node2.com:8080 loadfactor=2 route=Tomcat2
 ProxySet stickysession=ROUTEID
</Proxy>
  1. 重启服务
systemctl restart httpd
  1. 测试
curl --cookie 'ROUTEID=.Tomcat1; path=/' 127.0.0.1

curl --cookie 'ROUTEID=.Tomcat2; path=/' 127.0.0.1

配置 httpd ajp 方式实现负载均衡功能

  • httpd服务器上
  1. 修改配置
vim /etc/httpd/conf.d/vhost.conf 
...
<Proxy balancer://lbtomcats>
BalancerMember ajp://node1.com:8009 loadfactor=1 route=Tomcat1
BalancerMember ajp://node2.com:8009 loadfactor=2 route=Tomcat2
ProxySet stickysession=ROUTEID 
</Proxy>
  1. 重启服务
systemctl restart httpd
  1. 测试
curl -c cookies  127.0.0.1
  1. 查看
cat cookies 
# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_127.0.0.1     FALSE   /       FALSE   0       JSESSIONID      2CF0923D2F9046322300EDF3BCF1BB85

Httpd调度配置说明

ProxySet stickysession=ROUTEID 开启后,发现Session不变了,一直找的同一个Tomcat服务器。
虽然,上面的做法实现客户端在一段时间内找同一台Tomcat,从而避免切换后导致的Session丢失。但是如果Tomcat节点挂掉,那么Session依旧丢失。

负载均衡配置说明

配置代理到balancer

ProxyPass [path] !|url [key=value [key=value ...]]

设置Balancer成员

BalancerMember [balancerurl] url [key=value [key=value ...]]

设置Balancer或参数

ProxySet url key=value [key=value ...]

ProxyPass和BalancerMember指令参数

参数缺省值说明
min0连接池最小容量
max1- n 连接池最大容量
retry60apache请求发送到后端服务器错误后等待的时间秒数。0表示立即重试

Balancer参数
ProxySet指令也可以使用下面的参数。

参数缺省值说明
loadfactor定义负载均衡后端服务器权重,取值范围1 - 100
lbmethodbyrequests负载均衡调度方法。
byrequests 基于权重的统计请求个数进行调度;
bytrafficz 执行基于权重的流量计数调度;
bybusyness 通过考量每个后端服务器当前负载进行调度
maxattempts1放弃请求前实现故障转移的次数,默认为1,其最大值不应该大于总的节点数
nofailoverOff如果后端服务器没有Session副本,可以设置为On不允许故障转移。Off故障可以转移
stickysession调度器的sticky session名字,根据web后台编程语言不通
可以设置为JSESSIONID或PHPSESSIONID

在tomcat的配置中Engine使用jvmRoute属性

# t1、t2的tomcat配置中分别增加jvmRoute
<Engine name="Catalina" defaultHost="t1.magedu.com" jvmRoute="Tomcat1">
<Engine name="Catalina" defaultHost="t2.magedu.com" jvmRoute="Tomcat2">

这样SessionID,就变成了

SessionID = 9C949FA4AFCBE9337F5F0669548BD4DF.Tomcat2

Tomcat Session集群

官方文档:https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html

  • tomcat1上

接上面的实验

  1. 修改配置,来达到会话共享
vim /usr/local/tomcat/conf/server.xml

修改前需知:
添加到<Engine> 所有虚拟主机都可以启用Session复制
添加到<Host> ,该虚拟主机可以启用Session复制
添加到最后,在应用程序内部启用了才可以使用
另外: 要修改第二个address后面的ip为你的本机ip

<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="230.100.100.8"
            port="45564"
            frequency="500"
            dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
          address="修改我"
          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.MessageDispatchInterceptor"/>
</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>

本次把多播复制的配置放到缺省虚拟主机里面, 即Host之下。
特别注意修改Receiver的address属性为一个本机可对外的IP地址。

配置说明
+ Cluster 集群配置
+ Manager 会话管理器配置
+ Channel 信道配置
- Membership 成员判定。使用什么多播地址、端口多少、间隔时长ms、超时时长ms。同一个多播地址和端口认为同属一个组。使用时修改这个多播地址,以防冲突
- Receiver 接收器,多线程接收多个其他节点的心跳、会话信息。默认会从4000到4100依次尝试可用端口。
- address="auto",auto可能绑定到127.0.0.1上,所以一定要改为可以用的IP上去
- Sender 多线程发送器,内部使用了tcp连接池。
- Interceptor 拦截器
+ Valve
- ReplicationValve 检测哪些请求需要检测Session,Session数据是否有了变化,需要启动复制过程
+ ClusterListener
- ClusterSessionListener 集群session侦听器

  1. 时间同步,确保NTP或Chrony服务正常运行。
systemctl status chronyd

如果没有这个服务,则

yum -y install chronyd
systemctl restart chronyd
systemctl enable chronyd
  1. 准备web.xml
    在应用中增加WEB-INF,从全局复制一个web.xml过来
mkdir /data/webapps/ROOT/WEB-INF/
cp /usr/local/tomcat/conf/web.xml /data/webapps/ROOT/WEB-INF/
vim /data/webapps/ROOT/WEB-INF/web.xml
...
    <distributable/>
</web-app>  
为web.xml的 标签增加子标签 来开启该应用程序的分布式。
  1. 设置权限
chown -RL tomcat.tomcat /data/webapps
  1. 重启
su - tomcat -c "/usr/local/tomcat/bin/shutdown.sh"
su - tomcat -c "/usr/local/tomcat/bin/startup.sh"
  • tomcat2上
  1. 修改配置
vim /usr/local/tomcat/conf/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="230.100.100.8"
            port="45564"
            frequency="500"
            dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
          address="修改我"
          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.MessageDispatchInterceptor"/>
</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>

本次把多播复制的配置放到缺省虚拟主机里面, 即Host之下。
特别注意修改Receiver的address属性为一个本机可对外的IP地址。
  1. 时间同步,确保NTP或Chrony服务正常运行。
systemctl status chronyd
如果没有这个服务,则
yum -y install chronyd
systemctl restart chronyd
systemctl enable chronyd
  1. 准备web.xml
    在应用中增加WEB-INF,从全局复制一个web.xml过来
mkdir /data/webapps/ROOT/WEB-INF/
cp /usr/local/tomcat/conf/web.xml /data/webapps/ROOT/WEB-INF/
vim /data/webapps/ROOT/WEB-INF/web.xml
为web.xml的 标签增加子标签 来开启该应用程序的分布式。
重启全部Tomcat,通过负载均衡调度到不同节点,返回的SessionID不变了。
  1. 重启
su - tomcat -c "/usr/local/tomcat/bin/shutdown.sh"
su - tomcat -c "/usr/local/tomcat/bin/startup.sh"
  • 浏览器测试
在这里插入图片描述

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注