Tomcat集群能带来什么?

  1. 提高服务的性能、并发能力、以及高可用性
  2. 提高项目架构的横向扩展能力

提高服务的性能

实际公司线上生产环境都会选择一台机器部署一个tomcat,多台机器完成集群,毕竟一台机器部署多个tomcat还是有一些共享瓶颈的,例如它们的网卡只有一个,内存和磁盘IO等都是共用的。而多台机器共同提供相同的服务,能够充分利用每一台机器的资源,自然能够提高服务的性能。

并发能力

很好理解,一台tomcat的http线程池是有限的,那么两台能承载的http线程自然是一台的2倍。

高可用性

简单理解在Nginx下面挂了多台tomcat节点,当其中一台tomcat挂掉的时候,那么我们可以把这个节点从Nginx负载均衡tomcat集群的配置当中移除,那么对于请求nginx还会打到可用的tomcat服务器上,并不影响我们提供的服务。所以tomcat集群就能带来一定的高可用性。

横向扩展能力

假设对于一台服务器,通过不断的升级它的cpu、内存、更换固态硬盘等,我们认为这是纵向提高机器的配置,来达到提高tomcat所提供服务的性能,随着硬件不断提高,成本是指数级上升的。
而横向扩展能力则不同,比如天猫的双11活动,因为平时访问量没有那么高,但是双11访问量非常高,当tomcat集群完成后我们就可以做一个横向扩展,只要增加tomcat节点就可以了,根据实际数据、历史数据去做一个评估,当然这个还要有一定的动态能力,根据实际的情况动态的增加几个节点,让nginx进行热部署,就把新增的节点加入到集群中。

Tomcat集群实现原理

通过Nginx负载均衡对多个tomcat进行请求转发,也就是说将多个用户的请求通过一定的策略打到集群的各个tomcat服务器中。

Tomcat集群带来了什么新问题

1.Session登录信息存储及读取问题

通常在单tomcat环境下,我们都是将登录信息存储在原生提供的Session对象中。那么在集群环境下,当用户A发起登录请求被转发到tomcat1上,最终登录的session信息存储到了tomcat1上,用户A此时访问系统的某个服务,该请求被转发到了tomcat2上,但是tomcat2并没有该用户的登录信息,所以会提示用户未登录,显然这是不合理的。
所以在集群环境下我们必须要解决多个tomcat之间session共享问题,让用户只需要登录一次就可以继续访问其他的服务。

2.服务器定时任务并发的问题

当服务器存在定时任务时,假设配置的30分钟执行一次,那么到了执行的时间点,多个tomcat就会同时启动这个定时任务,带来的问题就是首先如果定时任务的业务逻辑很复杂时,非常容易造成线上的数据错乱,其次我们其实只希望有一台服务器去执行定时任务就够了,那么多台同时执行也会带来不必要的资源浪费。

3.根据项目架构和现有业务还有可能有更多的问题

对于实际不同的场景还会有很多的问题,所以随着项目架构的演进,从架构层面的变化会引起代码层面的变化以及解决方案的变化,不要想当然的认为集群就是多部署几台tomcat就行了。

Tomcat集群架构

如图为tomcat集群后简要的架构图,左侧是一个分布式的Redis Session Server,无论用户请求哪台tomcat,都将session信息存储在这里,tomcat请求session也都从这里获取。所以这里还需要做单点登录功能。
同时可以利用分布式Redis来做一个分布式锁,解决多个tomcat在同一时间点启动定时任务的问题。

Nginx负载均衡配置

负载均衡用于从 “upstream” 模块定义的后端服务器列表中选取一台服务器接受用户的请求。模块内的server是服务器列表。Nginx负载均衡常用策略主要有以下5种,下面进行分别介绍这几种策略,包括一些扩展的配置参数。

轮询

默认的负载均衡策略,每个请求会按时间顺序逐一分配到不同的后端服务器
优点:实现简单
缺点:不考虑每台服务器的处理能力

upstream www.silly.com{
    server 192.168.1.109:8080;
    server 192.168.1.111:8080;
}

权重

在轮询策略的基础上指定轮询的几率,通过weight参数指定轮询几率,权重(weight)越高分配到需要处理的请求越多。
weight默认值为1,如果多台都配置了权重,比较相对值,意思是说如果两台服务器一台权重为15,一台为10,只代表访问第一台的概率是第二台的1.5倍,而不是说25次访问,有15次访问第一台。
优点:考虑了每台服务器处理能力的不同(实际生产环境用的比较多的策略)

upstream www.silly.com{
    server 192.168.1.109:8080 weight=10;
    server 192.168.1.111:8080 weight=15;
}

ip hash

根据请求的IP,将IP进行哈希取模,分配到指定的服务器,对于同一客户端IP的请求将发送到相同的服务器。
优点:能实现同一个用户访问同一个服务器,可以解决session共享问题。
缺点:根据ip hash不一定分配平均,在IP变化的情况下也无法保证session会话。

upstream www.silly.com{
    ip_hash;
    server 192.168.1.109:8080;
    server 192.168.1.111:8080;
}

url hash

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器
优点:能实现同一个服务访问同一个服务器
缺点:根据url hash分配请求会不平均,请求频繁的url会请求到同一个服务器上

upstream www.silly.com{
    server 192.168.1.109:8080;
    server 192.168.1.111:8080;
    hash $request_uri;
}

fair

特点:按后端服务器的响应时间来分配请求,响应时间短的优先分配

upstream www.silly.com{
    server 192.168.1.109:8080;
    server 192.168.1.111:8080;
    fair;
}

参数扩展

down:表示当前的server暂时不参与负载
backup:当其他非backup的机器down或者忙的时候,请求backup机器
backup相当于备用机器,能提高项目架构的一定高可用性,用的不多,毕竟机器也是资源,需要成本

upstream www.silly.com{
    ip_hash;
    server 192.168.1.109:8080 down;
    server 192.168.1.111:8080 weight=2;
    server 192.168.1.112:8080;
    server 192.168.1.115:8080 backup;
}

Tomcat集群环境搭建

为了方便学习这里演示的是单机部署多应用,也就是说在一台Linux服务器上部署多个tomcat服务器,这里只配置两台tomcat,如果要配置更多台tomcat实例,方法是一样的,只需要保证tomcat的端口号必须不能重复,必须是系统没有使用的。

安装环境

CentOS安装参考:Linux安装
虚拟机使用参考:虚拟机的使用
tomcat安装参考:​​​​​​​​​​​​​​Linux离线安装Tomcat
nginx安装参考:Linux安装Nginx详细教程_nginx安装linux-CSDN博客

安装两个tomcat可以先解压下载的tomcat安装包,然后复制一份解压缩目录重命名即可。
这里将nginx和tomcat都安装在/usr/local目录下,tomcat目录分别命名为tomcat1和tomcat2。

配置环境变量

vim /etc/profile
# 在文件末尾添加如下内容
export CATALINA_BASE=/usr/local/tomcat1
export CATALINA_HOME=/usr/local/tomcat1
export TOMCAT_HOME=/usr/local/tomcat1

export CATALINA_2_BASE=/usr/local/tomcat2
export CATALINA_2_HOME=/usr/local/tomcat2
export TOMCAT_2_HOME=/usr/local/tomcat2
# 通过vim的 ":wq" 命令进行保存退出
# 使配置生效
source /etc/profile

修改两个tomcat的编码

vim ${tomcat}/conf/server.xml
进入tomcat安装目录,编辑conf目录下的server.xml文件,找到如下节点添加编码配置:URIEncoding="UTF-8"

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>

修改第二个tomcat的配置

修改第二个tomcat的bin目录下的catalina.sh文件,找到# OS注释内容,在其下面新增配置

vim /usr/local/tomcat2/bin/catalina.sh
# 新增如下配置
# OS specific support.  $var _must_ be set to either true or false.
export CATALINA_BASE=$CATALINA_2_BASE
export CATALINA_HOME=$CATALINA_2_HOME

修改第二个tomcat的conf目录下的server.xml文件,,修改3个端口配置

vim /usr/local/tomcat2/conf/server.xml
# 修改以下3个端口,修改为9005,9080,9009
<Server port="9005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  
<Connector port="9080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>
               
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" /> 

为了方便对两个tomcat进行区分,我们修改第二个tomcat的主页logo图片,即替换/usr/local/tomcat2/webapps/ROOT/tomcat.png,图片名保持一致。

防火墙配置

如果开启了防火墙,需要配置防火墙规则,先将两个tomcat的端口进行开放,主要是为了测试,在配置了Nginx负载均衡后就可以关闭端口了。

vim /etc/sysconfig/iptables
# 添加如下规则
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 9080 -j ACCEPT
# 重启iptables
service iptables restart

tomcat验证

分别启动两个tomcat,即执行命令:${tomcat}/bin/startup.sh
注意检查两个tomcat启动使用的环境变量是否正确。

分别访问两个tomcat,这里是在windows下访问虚拟机的IP + 端口。

host配置

由于我们是在本机进行搭建,所以需要配置host虚拟域名映射,如果是线上环境有真实域名,请忽略此步。
修改浏览器所在的主机的host文件,这里修改的是windows的host文件:C:\Windows\System32\drivers\etc
在末尾添加一行配置:192.168.0.109 www.silly.com
打开cmd,执行命令:ping www.silly.com,回复中显示的是虚拟机的IP则说明OK。

Nginx配置

  1. 修改nginx主配置文件nginx.conf
vim /usr/local/nginx/conf/nginx.conf
# 在注释内容上面添加如下内容
include vhost/*.conf;
# another virtual host

     2. 在Nginx安装目录的conf目录下新建一个vhost目录,然后在vhost目录下新建配置文件,文件           名需要以.conf结尾

cd /usr/local/nginx/conf/
mkdir vhost
cd vhost/
vim www.silly.com.conf

配置文件添加如下内容,这里server_name配置的是主机对应的域名proxy_pass是反向代理配置,upstream是负载均衡配置。

upstream www.silly.com{
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:9080 weight=2;
}

server {
    listen 80;
    autoindex on;
    server_name silly.com www.silly.com;
    access_log /usr/local/nginx/logs/access.log combined;
    index index.html index.htm index.jsp index.php;

    location / {
        proxy_pass http://www.silly.com;
        add_header Access-Control-Allow-Origin *;
    }
}

集群验证

启动Nginx,即执行命令:${nginx}/sbin/nginx,打开浏览器,清除缓存,访问域名http://www.silly.com,不停刷新浏览器,可以发现一会访问到了8080的tomcat,一会访问到了9090的tomcat,到此整个Tomcat集群及Nginx负载均衡环境也就搭建完成了,当然关于nginx的配置还有很多细节的配置项这里就不做介绍了。

多机部署多应用

事实上多机部署多应用更加简单,所以学会单机部署多应用也就自然能搞定实际生成环境多机的部署了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐