tomcat-负载均衡实现

tomcat-负载均衡实现,第1张

tomcat-负载均衡实现 实现负载均衡

动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载均衡。

当单机的Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由来,都是由于HTTP协议在设计之初没有想到未来的发展。

HTTP的无状态,有连接和短连接
    无状态:指的是服务器端无法知道2次请求之间的联系,即使是前后2次请求来自同一个浏览器,也没有任何数据能够判断出是同一个浏览器的请求。后来可以通过cookie、session机制来判断。
    
      浏览器端第一次HTTP请求服务器端时,在服务器端使用session这种技术,就可以在服务器端产生一个随机值即SessionID发给浏览器端,浏览器端收到后会保持这个SessionID在cookie当中,这个cookie值一般不能持久存储,浏览器关闭就消失。浏览器在每一次提交HTTP请求的时候会把这个SessionID传给服务器端,服务器端就可以通过比对知道是谁了
      Session通常会保存在服务器端内存中,如果没有持久化,则易丢失
      Session会定时过期。过期后浏览器如果再访问,服务端发现没有此ID,将给浏览器端重新发新的SessionID
      更换浏览器也将重新获得新的SessionID
    有连接:是因为它基于TCP协议,是面向连接的,需要3次握手、4次断开。
    短连接:Http 1.1之前,都是一个请求一个连接,而Tcp的连接创建销毁成本高,对服务器有很大的影响。所以,自Http 1.1开始,支持keep-alive,默认也开启,一个连接打开后,会保持一段时间(可设置),浏览器再访问该服务器就使用这个Tcp连接,减轻了服务器压力,提高了效率。

服务器端如果故障,即使Session被持久化了,但是服务没有恢复前都不能使用这些SessionID。

如果使用HAProxy或者Nginx等做负载均衡器,调度到了不同的Tomcat上,那么也会出现找不到SessionID的情况。

会话保持方式 session sticky会话黏性

Session绑定

    nginx:source ip
    HAProxy:cookie

优点:简单易配置

缺点:如果目标服务器故障后,如果没有做sessoin持久化,就会丢失session

session复制集群

Tomcat自己的提供的多播集群,通过多播将任何一台的session同步到其它节点。

缺点

    Tomcat的同步节点不宜过多,互相即时通信同步session需要太多带宽
    每一台都拥有全部session,内存损耗太多
session server

session 共享服务器,使用memcached、redis做共享的Session服务器,此 为推荐方式

负载均衡规划和准备 负载均衡主机和网络地址规划 IP 主机名 服务 软件 10.0.0.100 proxy 调度器 Nginx、HTTPD 10.0.0.101 t1 tomcat1 JDK8、Tomcat8 10.0.0.102 t2 tomcat2 JDK8、Tomcat8
只在10.0.0.100的nginx主机上实现域名解析
vim /etc/hosts 
#添加以下三行
10.0.0.100 proxy.magedu.org proxy
10.0.0.101 t1.magedu.org t1
10.0.0.102 t2.magedu.org t2
负载均衡tomcat主机准备

t1虚拟主机配置conf/server.xml


    
    

t2虚拟主机配置conf/server.xml


    
    

负载均衡规划测试用jsp文件

t1和t2节点的/data/webapps/index.jsp

#项目路径配置
mkdir -pv /data/webapps/ROOT

#编写测试jsp文件,内容在下面
vim /data/webapps/index.jsp
<%@ page import="java.util.*" %>



    
    lbjsptest


On  <%=request.getServerName() %>
<%=request.getLocalAddr() + ":" + request.getLocalPort() %>
SessionID = <%=session.getId() %>
<%=new Date()%>

Nginx实现后端tomcat的负载均衡调度

nginx配置如下

vim /etc/nginx/nginx.conf  
#注意名称不要用下划线
upstream tomcat-server {
        #ip_hash; # 先禁用看看轮询,之后开启开黏性
        server t1.magedu.org:8080;
        server t2.magedu.org:8080;
}

server {
        location ~* .(jsp|do)$ {
        proxy_pass http://tomcat-server;
        }
}

测试http://proxy.magedu.com/index.jsp,可以看到轮询调度效果

[root@proxy ~]#curl http://proxy.magedu.org/index.jsp




    
    lbjsptest


On  tomcat-server
10.0.0.101:8080
SessionID = 1A5B0811ADA103936F2E9A50D303DFD3
Tue Feb 11 20:14:53 CST 2020


[root@proxy ~]#curl http://proxy.magedu.org/index.jsp




    
    lbjsptest


On  tomcat-server
10.0.0.102:8080
SessionID = 7EB9ACEEE6FD99E3471CCFC0AAA7F37C
Tue Feb 11 20:14:54 CST 2020


使用抓包wireshark工具可以看到下面信息












在upstream中使用ip_hash指令,使用客户端IP地址Hash。

[root@proxy ~]#vim /etc/nginx/nginx.conf
#只添加ip_hash;这一行
upstream tomcat-server {
        ip_hash;  #启动源地址hash                                                          
        server t1.magedu.org:8080;
        server t2.magedu.org:8080;
}

配置完reload nginx服务。测试一下看看效果。

[root@proxy ~]#curl http://proxy.magedu.org/index.jsp




    
    lbjsptest


On  tomcat-server
10.0.0.102:8080
SessionID = F95A1F77FC476D6B1092A9336599CE86
Tue Feb 11 20:20:10 CST 2020


[root@proxy ~]#curl http://proxy.magedu.org/index.jsp




    
    lbjsptest


On  tomcat-server
10.0.0.102:8080
SessionID = EC923AF799697155CF6F74B4677C07BE
Tue Feb 11 20:20:11 CST 2020



#每次都调度到10.0.0.102主机上,但SessionID每次都在变化

通过浏览器看到主机不变,sessionID也不变



关闭Session对应的Tomcat服务,再重启启动它,看看Session的变化。

[root@t2 ~]#systemctl restart tomcat

通过浏览器看到主机不变,但sessionID和上一次变化,但后续刷新不再变化



Httpd实现后端tomcat的负载均衡调度 httpd的负载均衡配置说明

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

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

负载均衡配置说明

配置代理到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指令参数

参数 缺省值 说明 min 0 连接池最小容量 max 1 – n 连接池最大容量 retry 60 apache请求发送到后端服务器错误后等待的时间秒数。0表示立即重试

Balancer参数

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

RroxySet指令也可以使用上面的参数。

启用httpd的负载均衡

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

#t1的conf/server.xml配置如下:

                   

#t2的conf/server.xml配置如下:

                 

这样SessionID,就变成了示例形式:SessionID = 9C949FA4AFCBE9337F5F0669548BD4DF.Tomcat2

httpd配置如下

[root@proxy ~]#vim /etc/httpd/conf.d/tomcat.conf 
[root@proxy ~]#cat /etc/httpd/conf.d/tomcat.conf

    ServerName        proxy.magedu.org
    ProxyRequests     Off
    ProxyVia          On
    ProxyPreserveHost On  #off时不向后端转发原请求host首部,而转发采用BalancerMember指向名称为首部
    ProxyPass        / balancer://tomcat-server/
    ProxyPassReverse / balancer://tomcat-server/



    BalancerMember http://t1.magedu.org:8080 loadfactor=1
    BalancerMember http://t2.magedu.org:8080 loadfactor=2

loadfactor设置为1:2,便于观察。观察调度的结果是轮询的。





使用抓包wireshark工具可以看到下面信息









使用session黏性

官方文档:http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html

[root@proxy ~]#vim /etc/httpd/conf.d/tomcat.conf 
Header add Set-cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

    ServerName        proxy.magedu.org
    ProxyRequests     Off
    ProxyVia          On
    ProxyPreserveHost On
    ProxyPass        / balancer://tomcat-server/
    ProxyPassReverse / balancer://tomcat-server/



    BalancerMember http://t1.magedu.org:8080 loadfactor=1 route=Tomcat1
    BalancerMember http://t2.magedu.org:8080 loadfactor=2 route=Tomcat2
    ProxySet stickysession=ROUTEID

发现Session不变了,一直找的同一个Tomcat服务器



关闭tomcat2的tomcat服务,再查看,转向另一台tomcat服务器

[root@t2 ~]#systemctl stop tomcat



ajp调度

在上面基础上修改httpd的配置文件

[root@proxy ~]#cat  /etc/httpd/conf.d/tomcat.conf 
#Header add Set-cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

    ServerName        proxy.magedu.org
    ProxyRequests     Off
    ProxyVia          On
    ProxyPreserveHost On
    ProxyPass        / balancer://tomcat-server/
    ProxyPassReverse / balancer://tomcat-server/



    BalancerMember ajp://t1.magedu.org:8009 loadfactor=1 route=Tomcat1
    BalancerMember ajp://t2.magedu.org:8009 loadfactor=2 route=Tomcat2
    #ProxySet stickysession=ROUTEID

ProxySet stickysession=ROUTEID先禁用看看切换效果,开启后看看黏住效果。





抓包可以可看AJP13协议









开启后,发现Session不变了,一直找的同一个Tomcat服务器。

[root@proxy ~]#vim /etc/httpd/conf.d/tomcat.conf 
#只修改下面一行
    ProxySet stickysession=ROUTEID                                                       
[root@proxy ~]#systemctl restart httpd

多次刷新页面,不再变化



虽然,上面的做法实现客户端在一段时间内找同一台Tomcat,从而避免切换后导致的Session丢失。但是如果Tomcat节点挂掉,那么Session依旧丢失。

[root@t2 ~]#systemctl stop tomcat




假设有A、B两个节点,都将Session持久化。如果Tomcat A服务下线期间用户切换到了Tomcat B上,就获得了Tomcat B的Session,原有Sesssion将丢失,就算将持久化Session的Tomcat A上线了,也没用了。因此需要实现Session的高可用性来解决上述问题。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/3012901.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-28
下一篇 2022-09-28

发表评论

登录后才能评论

评论列表(0条)

保存