Nginx +Tomcat 集群+memcached 实现负载均衡和session共享[理论篇]

能够解决的问题

这是一位作者的描述 我觉得很清晰明了

1 起因http://m.blog.csdn.net/article/details?id=7466420
最近对新开发的web系统进行了压力测试,发现tomcat默认配置下压到600人的并发登录首页响应速度就有比较严重的影响,一轮出现2000多个的500和502错误。我把登录的时间统计做了一下,把服务器处理总时间打印出来,看了一下发现有个别响应确实在20秒,但平均时间和lr测试出来的还是相差很远。所以可以断定不是程序处理处理花费了这么多时间,由于在局域网测试,所以也可以排除网络问题。这就把问题圈定在tomcat的请求响应能力上了。先把tomcat线程数提升到1000,发现500和502的报错降到几十个,但是响应时间上还没什么提高。后来启动了2个tomcat,用 nginx做负载均衡,响应时间下降了40%,两个tomcat的处理时长都保持在1秒左右。
看来tomcat性能确实是系统的一个瓶颈,很有必要假设多个服务器来加强响应能力。之前由于只是测试登录,多个tomcat还不用共享session,但真正使用时是必须要能一起工作的。现记录一下负载均衡的安装配置过程。

Nginx

Nginx (发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。 其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、 腾讯,另外知名的微网志Plurk也使用nginx。
这里写图片描述

NGINX负载的几种方式
nginx 的 upstream目前支持 4 种方式的分配
1)、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2)、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
2)、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,
ip_hash其实上不能够完全解决ip问题,因为有很多用户的ip随时都可能在变动,ip_hash这个名字你就知道,是通过hash散列的原理将用户的ip散列到指定的tomcat上,自然而然的想当然的解决了session问题,最好是用memcached存取来实现session共享
3)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
4)、url_hash(第三方)’

负载均衡之后的会话处理问题

使用nginx和Tomcat集群可以很容易的实现负载均衡,难点在于比如一个浏览器访问tomcat1产生一个seesion之后的访问如果分发到tomcat2上去了 就会产生两个session 无法进行会话管理。

解决sesson问题的几种方案

负载均衡会话处理主要方式:粘滞session,session共享和不用session。
链接:https://www.zhihu.com/question/27085849/answer/61232544

粘滞session(不考虑了。)
当用户发出第一个request后,负载均衡器动态的把该用户分配到某个节点,并记录该节点的路由,以后该用户的所有request都绑定到这个路由,用户只会与该server发生交互,这种策略被称为粘性session(session sticky)
利用nginx的基于访问ip的hash路由策略,保证访问的ip始终被路由到同一个tomcat上,这个配置更简单。但是我们的应用很可能是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了。而且面对复制网络环境并不能解决session问题。


session共享
tomcat本身自带session复制功能,开启server.xml中的cluster节点,做相应的配置即可。参见[官方文档][1]。tomcat本身的session复制功能并不好用,官方文档也说方式只适合小集群:
This works great for smaller cluster but we don’t recommend it for larger clusters(a lot of Tomcat nodes).使用tomcat自带的cluster方式,多个tomcat见自动实时复制session信息,配置起来很简单。但这个方案的效率比较低,在大并发下表现并不好。
于是乎大家就”自己动手,丰衣足食”了,自己包装session,并使用第三方存储(例如memcached)来存储session,从而实现session共享,例如[memcached-session-manager][2]。但由于memcached的缓存剔除机制,使用memcached存储session是不靠谱的,参见[这篇文章][3]。之前使用[memcachedb][4](即memcached+bdb)可以应对这个问题。
其他:Redis ,spring session(不太了解)


不使用session
HTTP本身就是无状态的,应用服务器为了跟踪用户状态而强行加入了session。服务器为了保存用户状态就需要做额外的工作。
于是乎,Token-based的身份校验因其伸缩性而广受欢迎。在用户登录后,服务器返回一个token给用户,用户后续的请求都需要附带此token,服务器会校验该token来判断用户身份,进而完成具体业务(这里掠过不谈token的安全防护问题)。

Memcached

Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
http://blog.csdn.net/bluishglc/article/details/7641714
1. 来源
多数的应该服务器(包括Tomcat在内)使用的是session复制(session replication)机制,即结点之间通过组播方式将各自的session发到其他所有结点上,如果其中一个访问出错,则另外结点仍然具有有效的session内容,从而能正常接管其session。由于服务器内置了session复制机制的实现,因而使用这种方案非常简单,只需要做简单的配置即可完成,但是其缺点也是很明显的,由于大量的session信息需要复制,在用户数量和集群数量达到一定规模后,session复制就有可能成为性能瓶颈。于是人们想到了别外一种解决策略:通过第三方缓存来存放sessiono数据,如果某一结点失效,被委任接替失效结点的服务器可以从缓存中恢复session.基于这种思想,在google code上有一款开源产品:memcached-session-manager。
2. memcached-session-manager的工作原理
首先,所有的tomcat节点需要安装memcached-session-manager,每一个tomcat会有自己的本地session,当一个请求执行完毕之后,如果对应的session之前不存在(也就是说这是某个用户的第一次请求),则将该session拷贝一份副本至memcached缓存,当该session的下一个请求到达时,会使用tomcat的本地session,请求处理结束之后,session的变化会同步更新到memcached缓存中对应的session里,从而确保本地session和缓存中的session始终保持一致。如果当前结点失效,下一个请求会被路由给另外一个tomcat处理,这个tomcat发现请求所属的session并不存在,于是它将查询memcached缓存,并将查询到的session恢复到本地,这样就完成了容错处理。(以上是sticky session模式为背景的解释,memcached-session-manager也支持non-sticky session。)
由于以缓存为基础的session管理不需要大量的数据复制,其性能表现更好,具有更好的伸缩性。
最后补充一点:实际上,除去有服务器端管理session,还有另一个种截然不同的管理方式,即将session作为cookie的一部分经过压缩和加密后存放在用户的本地浏览器上!

memcached 几种序列化方式

多个tomcat各种序列化策略配置如下:
一、java默认序列化tomcat配置
二、javolution序列化tomcat配置
三、xstream序列化tomcat配置
四、flexjson序列化tomcat配置
五、kryo序列化tomcat配置
各种情况配置如上,据说kryo序列化效率比较快,未做测试。


附:http://blog.csdn.net/hejingyuan6/article/details/50819100

1,当session未实现共享时,两台tomcat服务器权重比为1:1
效果:刷新浏览器,每次的sessionid均不同

这里写图片描述
原因:当浏览器首次访问时,创建session,然后将sessionid存放到浏览器的cookie中,当浏览器再次刷新或者访问其他页面时,本地有sessionid,但是此时的请求被分发到另一台服务器上,本地带过去的sessionid在新的服务器上并找不到对应的session,故重新产生session。so 每次刷新都是不同的sessionid,session无法共享。

2,当session实现共享时,两台tomcat服务器权重比为1:1
效果:刷新浏览器,每次的sessionid不变,但是打印的This is tomcat server 值会变
这里写图片描述
原因:当浏览器首次访问时,创建session,并将sessionId存到浏览器中,那么当用户再刷新浏览器或者访问其他页面时,我们客户端的请求会带上sessionid,然后我们通过sessionid去查找session,此时无论请求分发到哪个服务器上面,我们均可以找到session,因为我们将session存储到memcached服务器上了,故session不会重新创建,也就session共享了。

ps:这都是我看的大神的博客整理的,我可能有理解错误的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值