众人拾柴火焰高之Tomcat集群
一人拾柴火不旺,众人拾柴火焰高。Tomcat服务器也是一样,一台服务器再强大能承受的访问也是有限的。要提供高并发、高可用的服务,就必须横向扩展,多台Tomcat组成一个集群,根据实际的访问量动态增减服务器的部署。
负载均衡的难点
我们一般用session来保持会话,所以Tomcat服务器是有状态的。坏处是当一台宕机后自动跳转到另一台服务器可能会导致用户会话失效,最明显的例子就是要重新登录。所以以下的几种方法,都是在围绕session的问题。
方案一、使用Tomcat自带的session同步功能
如果我们使用nginx作为负载均衡服务器,它默认使用是轮询策略(也就是第一次请求分给服务器A,第二次分配给B,以此类推)。这种方案非常简单,但是别忘了我们的session是放在访问服务器上,轮询得结果是下次我们可能访问的是另一台服务器了,导致我们的会话不能保持。
其实,解决起来也似乎很简单,就是创建session时,只需要把它复制给集群中的所有服务器就行了,下次不管访问哪一台Tomcat,它都能根据sessionID找到我们的session。非常幸运的是,Tomcat本身就已经帮我们实现了这个功能——session复制。我们只需简单两步配置即可:
在server.xml中打开以下注释:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>在tomcat或者应用下web.xml,添加:
<distributable/>是不是非常简单实用呢。
简单归简单,不得不提的是,它有一个缺点,因为它默认使用BackupManager,是all-to-all的复制,所以如果大量节点的集群会有广播风暴,而且即使没有部署应用的节点也会复制。所以对大规模的集群,这种方案需谨慎考虑哦。
方案二、使用nginx的ip_hash策略
上面说了,nginx默认实用的是轮询策略,所以得配合session复制功能,才能保持会话。其实我们有一个更简单的方法,实用nginx的ip_hash策略。顾名思义,就是对ip进行hash散列,ip散列后找到指定的服务器,下次就一直访问这台服务器,这样一来,就不需要session复制了。
配置起来也非常简单,nginx自身支持,只需在nginx配置中添加配置即可,Tomcat不需要任何处理:
upstream mywebsite {
server 110.119.88.1:8080;
server 110.119.88.1:8080;
ip_hash;
}
凡事都有两面,它简单但也有一些缺点:
- nginx必须作为最前端的服务器,否则得不到正确的ip(自己暂未证实)
- nginx后不能再有其他的负载均衡,否则不能保证每次访问的是同一台服务器(未证实,不过按理应该是这样)
- 同一局域网下的多个用户可能每次访问的都是同一服务器。如我们的应用是给一个单位使用,使用ip_hash分流会很不理想
- 如果一台服务器挂了之后,自动跳转到另一台服务器,没有session,会需要重新登录
方案三、使用nginx的nginx_upstream_jvm_route扩展模块
上面两种方案都是nginx已支持的策略,接下来这种需要在nginx安装扩展模块。配置起来稍微复杂一些,需要完成以下三个步骤:
- 为nginx添加扩展模块
Tomcat的server.xml标注jvmRoute
<Engine name="Catalina" defaultHost="localhost" jvmRoute="a">配置文件nginx.conf中指明负载策略
jvm_route $cookie_JSESSIONID;需要注意的是,这个模块通过session和cookie实现会话保持,如果url没有添加sessionid,或者用户禁用了浏览器cookie,则使用nginx默认的轮询,也就不会保持会话了。
同样,他也有很大的缺点:我在配置实用时,没有找到支持nginx最新版本jvm_route,只找到支持nginx1.6的模块。
方案四、使用Memcached或Redis统一管理session
和上面的比起来,这个方案在大规模集群中更合理,管理起来更方便。
使用Memcached或者redis集中管理session,而不是让Tomcat管理,所以每个Tomcat都是对等的、无状态的,集群便可以随意增减Tomcat了。使用的Memcached_Session_Manager管理session,安装Memcached服务器后,配置起来比较简单,就是在tomcat的context.xml配置中,指定使用Memcached管理器来管理session。
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:memcached_server_ip:11211"
requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"
sessionBackupAsync="false"
sticky="false"
sessionBackupTimeout="100"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
copyCollectionsForSerialization="false" />
总结
没有最好的,只有最适合的,综合实际情况,选择最适合当前项目的方案才是最好的方案。
众人拾柴火焰高之Tomcat集群的更多相关文章
- 整合apache+tomcat+keepalived实现高可用tomcat集群
Apache是一个强大的Web服务器在处理静态页面.处理大量网络客户请求.支持服务的种类以及可配置方面都有优势,高速并且强壮.但是没有JSP/Servlet的解析能力.整合Apache和Tomcat可 ...
- Keepalived+Nginx+Tomcat 实现高可用Web集群
https://www.jianshu.com/p/bc34f9101c5e Keepalived+Nginx+Tomcat 实现高可用Web集群 0.3912018.01.08 20:28:59字数 ...
- 【原创】Tomcat集群环境下对session进行外部缓存的方法(2)
Session对象的持久化比较麻烦,虽然有序列化,但是并不确定Session对象中保存的其他信息是否可以序列化,这可能是网上很多解决方案摒弃此种做法的原因,网上的很多做法都是将Session中的att ...
- Tomcat集群配置学习篇-----分布式应用
Tomcat集群配置学习篇-----分布式应用 现目前基于javaWeb开发的应用系统已经比比皆是,尤其是电子商务网站,要想网站发展壮大,那么必然就得能够承受住庞大的网站访问量:大家知道如果服务器访问 ...
- Linux+Apache+Tomcat集群配置
参考: http://blog.csdn.net/bluishglc/article/details/6867358# http://andashu.blog.51cto.com/8673810/13 ...
- linux+apache+mod_Jk+tomcat实现tomcat集群
最近一段时间一直在研究实现apache + jk_mod + tomcat实现负载均衡,起初负载均衡算是配置蛮顺利的,但是到了配置tomcat集群时所有配置都没有问题,但是tomcat日志中一直提示没 ...
- apache、mod_jk负载均衡与tomcat集群
最近需要搭建apache和tomcat的集群,实现静态网站直接通过apache访问,动态网站转交给tomcat处理,实现负载均衡和tomcat集群配置. apache安装 wget http://ap ...
- 【转】Tomcat集群Cluster实现原理剖析
此文章来源:http://zyycaesar.iteye.com/blog/296606 此文章作者:zyycaesar 对于WEB应用集群的技术实现而言,最大的难点就是如何能在集群中的多个节点之间保 ...
- Linux下搭建tomcat集群全记录(转)
本文将讲述如何在Linux下搭建tomcat集群,以及搭建过程中可能的遇到的问题和解决方法.为简单起见,本文演示搭建的集群只有两个tomact节点外加一个apache组成,三者将安装在同一机器上:ap ...
随机推荐
- [Unity Shader]光照模型对物体的假设
什么是光照模型 光照模型就是模拟光在物体间的传递过程,以确保物体可见表面每一点的亮度和颜色. 当光照射到一个物体表面时,光可能被吸收.反射或折射.反射和折射的光使物体可见.如果入射光全部被吸收,物体将 ...
- arduino pro mini不能下载
刚毕业时就知道arduino,但当时崇拜技术极致,喜欢把单片机的性能用到尽,觉得操作寄存器运行效率高,对arduino 这种高效模式贬为投机取巧,不过其中也一直对arduino 有关注. 随着芯片技术 ...
- MongoDB 3.0 WiredTiger Compression and Performance
MongoDB3.0中的压缩选项 在MongoDB 3.0中,WiredTiger为集合提供三个压缩选项: 无压缩 Snappy(默认启用) – 很不错的压缩,有效利用资源 zlib(类似gzip) ...
- 基于STM32的USB枚举过程学习笔记
源:基于STM32的USB枚举过程学习笔记 基于STM32的USB枚举过程学习笔记(一) 基于STM32的USB枚举过程学习笔记(二) 基于STM32的USB枚举过程学习笔记(三) 基于STM32的U ...
- .NET防止重复提交数据
最近在做一个销售系统的时候,操作人员提交数据的时候数据库竟然会出现多条数据相同的记录,并且是在1秒之内,客户反馈给我们,第一反应是重复提交的问题,检查了下代码,程序执行完成后应该是跳转到别的页面的,可 ...
- SQL Server 2012 - 数据库的基础操作
数据库基本操作 --新建数据库卡 use master go create database SchoolDB on ( Name=SchoolDB, FileName='D;\DB\SchoolDB ...
- ubuntu 16.04 php 安装curl方法
先查看自己的php是否已经安装了curl.方法如下:1.在web服务器目录( Ubuntu下的通常为 /var/www )新建test.php文件2.编辑文件,键入下面一行代码:<?php ph ...
- js 如何判断鼠标点击事件还是js代码调用
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- Java经典案例之-“最大公约数和最小公倍数”
/** * 描述:输入两个正整数m和n,求其最大公约数和最小公倍数.(最大公约数:最大公约数, * 也称最大公因数.最大公因子,指两个或多个整数共有约数中最大的一个.) * (最小公倍数:几个数共有的 ...
- mysql 常用技巧
1.正则使用 比 LIKE 会牺牲很多的系统资源 尽量不要用 正则的语法和JS PHP 差不多 select * from t1 where email REGEXP "@163[,.]co ...