【Tomcat技术专题】「分布式技术架构」 探索Tomcat集群架构原理和开发分析指南

Tomcat集群原理

通过Nginx负载均衡进行请求转发

Tomcat集群能带来什么

  • 提高服务的性能, 并发能力, 以及高可用性
  • 提供项目架构的横向扩展能力

Tomcat集群产生什么问题

  • Session登录信息存储以及读取的问题
  • 服务器定时任务并发的问题

Tomcat 单服务体系架构

在这个架构图中,一层Nginx,首先Nginx主要职责给Tomcat一层反向代理。

此外,Nginx还可以FTPServer指定的目录再做一层目录转发,保证上传上去的图片实时可以通过http协议访问到。单服务架构先不用考虑集群碰到的各种问题

Tomcat集群"简单版"

比如,我们的登录的时候登录了A服务器,session信息存储到A服务器上了,假设我们使用的负载均衡策略是ip hash,那么登录信息还可以从A服务器上访问,但是这个有可能造成某些服务器压力过大,某些服务器又没有什么压力,这个时候压力过大的机器(包括网卡带宽)有可能成为瓶颈,并且请求不够分散。

首先要解决Session共享的问题

这时候我们使用轮询或者最小连接负载均衡策略,就导致了,第一次访问A服务器,第二次可能访问到B服务器,这个时候存储在A服务器上的session信息在B服务器上读取不到。

典型负载均衡策略分析

打个比方,我们有轮询,权重,地址散列,地址散列又分为原ip地址散列hash,目标ip地址散列hash,最少连接,加权最少连接,还有继续升级的很多种策略

  • 轮询:优点:实现简单,缺点:不考虑每台服务器处理能力
  • 权重:优点:考虑了服务器处理能力的不同
  • 地址散列:优点:能实现同一个用户访问同一个服务器
  • 最少连接:优点:使集群中各个服务器负载更加均匀
  • 加权最少连接:在最少连接的基础上,为每台服务器加上权值。算法为(活动连接数*256+非活动连接数)/权重,计算出来的值小的服务器优先被选择。
Session管理-Session Sticky粘滞会话:

对于同一个连接中的数据包,负载均衡会将其转发至后端固定的服务器进行处理。

解决了我们session共享的问题,但是它有什么缺点呢?

  • 一台服务器运行的服务挂掉,或者重启,上面的 session 都没了
  • 负载均衡器成了有状态的机器,为以后实现容灾造成了羁绊
Session管理-Session 复制

就是每一个Tomcat都存储我们的Session,不同的tomcat之间进行拷贝复制。

解决了我们session共享的问题,但是它有什么缺点呢?

  • 应用服务器间带宽问题,因为需要不断同步session数据
  • 大量用户在线时,服务器占用内存过多
Session管理-基于Cookie

主要用于我们将session会话如同token一般存储在我们的前端

解决了我们session共享的问题,但是它有什么缺点呢?

  • cookie 的长度限制
  • cookie存于浏览器,安全性是一个问题
Session管理-Session 服务器

就是通过一个专门管理session会话的管理器服务,进行集中化存储和管理session

解决了我们session共享的问题,这种方案需要思考哪些问题呢?保证 session 服务器的可用性,session服务器单点如何解决?

  • 我们在写应用时需要做调整存储session的业务逻辑
  • 打个比方,我们为了提高session server的可用性,可以继续给session server做集群

Tomcat单机部署多应用

  1. 解压2个tomcat, 分别命名为tomcatA和tomcatB

  2. 分别设置2个tomcat的URIEncoding, 将tomcat的conf/server.xml里的port修改为两个不同端口。

设置tomcat的环境变量

tomcatA的环境变量和以往一样, 不做改变

设置tomcat的环境变量

sudo vim /ect/profile

在profile文件里新增
javascript 复制代码
export CATALINA_BASE=/Users/tomcat/apache-tomcat-9.0.21
export CATALINA_HOME=/Users/tomcat/apache-tomcat-9.0.21
export TOMCAT_HOME=/Users/tomcat/apache-tomcat-9.0.21
javascript 复制代码
export CATALINA_2_BASE=/Users/tomcat/tomcat2
export CATALINA_2_HOME=/Users/tomcat/tomcat2
export TOMCAT_2_HOME=/Users/tomcat/tomcat2
强制保存退出

继续配置tomcatB下的catalina.sh里的内容,

cd tomcat目录,在# OS specific support. $var must be set to either true or false.下加入。

ini 复制代码
sudo vi catalina.sh
export CATALINA_BASE=$CATALINA_2_BASE
export CATALINA_HOME=$CATALINA_2_HOME
执行刷新环境变量

source /etc/profile

使环境变量生效, 执行

echo $CATALINA_2_BASE

如果有输出, 即环境变量已经生效

/Users/tomcat/tomcat2

分别进入两个tomcat下的bin目录启动tomcat, 正常即可

配置nginx

修改host

sudo vim /etc/hosts

所谓tomcat集群,就是可以向外提供并行服务的多台机器,任何一台服务器宕机,其它服务器可以替代它向外提供服务,而不影响用户访问。

nginx是一个常用的反向代理服务,可自定义模块,实现请求转发及负载均衡(根具体采用策略有关)。为了tomcat集群的高可用性,还需要实现nginx的双机热备。

一,如果仅是对外提供一个页面访问,不用区分单一用户(不区分每个访问session,不涉及用户权限,用户资料等内容),仅仅配置nginx负载均衡策略即可。

nginx负载均衡策略主要分一下四种:
1)、轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器宕机,能自动剔除。
2)、ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器。
3)、fair 按后端服务器的响应时间来分配请求,响应时间短的优先分配。
4)、url_hash 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

二,如果涉及到用户session,做一些鉴权缓存、存放临时信息时,就必须做tomcat的session共享。

目前可参考到的session共享方式主要分为两种。

1)利用tomcat自带的组播机制,实现session复制。

对tomcat及应用的若干配置文件进行配置即可实现,网上有很多资料可参考。但这种方式些弊端,看过一些资料,不建议用session复制的方式。在实际使用过程中,也发现有存在session莫名失踪的现象。

2)利用第三方机制存储session。

比较常见的是tomcat集成memcached服务器来存储session。实际项目中,我们采用过利用redis实现session存储,redis高效的存取性能为高效的访问提供了保障,但是目前redis的集群功能似乎没有发布,如何解决redis的单点故障需要研究。

小结:是否实现session共享与nginx的负载策略有很大关系。比如采用轮询策略,就必须实现session共享,因为客户端会访问到每台服务器;而如果采用ip_hash策略,就可以不用考虑session共享的问题了,但是ip_hash有些缺陷使它不能随便使用(如多台pc使用同一个外网ip)。

最近发现一个nginx的粘连模块(类似session粘连),可以看做nginx的第5种均衡策略。它利用客户端cookie,对其写入一个route参数,每次访问可以根据route的值,固定的访问一台服务器,解决的session共享的问题。

相关推荐
苍何43 分钟前
30分钟用 Agent 搓出一家跨境网店,疯了
后端
ssshooter1 小时前
Tauri 2 iOS 开发避坑指南:文件保存、Dialog 和 Documents 目录的那些坑
前端·后端·ios
追逐时光者1 小时前
一个基于 .NET Core + Vue3 构建的开源全栈平台 Admin 系统
后端·.net
程序员飞哥1 小时前
90后大龄程序员失业4个月终于上岸了
后端·面试·程序员
彭于晏Yan3 小时前
Redisson分布式锁
spring boot·redis·分布式
GetcharZp3 小时前
Git 命令行太痛苦?这款 75k Star 的神级工具,让你告别“合并冲突”恐惧症!
后端
Victor3564 小时前
MongoDB(69)如何进行增量备份?
后端
Victor3564 小时前
MongoDB(70)如何使用副本集进行备份?
后端
千寻girling4 小时前
面试官 : “ 说一下 Python 中的常用的 字符串和数组 的 方法有哪些 ? ”
人工智能·后端·python
ywf12155 小时前
Spring Boot接收参数的19种方式
java·spring boot·后端