文档章节

集群环境下的用户会话方案

南湖船老大
 南湖船老大
发布于 2016/10/02 11:52
字数 1422
阅读 86
收藏 1

集群环境下,必然需要考虑用户和会话的问题,如果不加处理的话,由于每一个会话cookies是对应服务器后端的一个session(Java是jsessionid,PHP是PHPSESSID),也就是说session是和具体的服务器绑定的,一旦后端IP轮询切换,会话cookies找不到对应的session,会话也就断了。在这种场景下,就存在5种处理方案。下文主要讨论的是Java和PHP的处理,对于其他语言一样适用。

    1、依然使用集群,但集群的轮训策略使用hash ip,将每一个客户和后端服务器绑定,这样一来,用户的会话始终落在一台固定的服务器上,这也是成本最小的方案。如果是很老的架构的话,这种方案是改造成本最小的。

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server.backend3.example.com;
}

但这样存在一个问题,就是一旦某台服务器挂了,切换到另外一台服务器后,对应的会话也就丢了。还存在一个情况就是如果前端是CDN的话,客户端IP可能变化的频率是很高的,有可能是一个小时或更短就变一次,在校园网这种网络环境下也容易产生这种情况。

2、使用session复制方案。这是早期tomcat采用的方案。

    session复制模式就可以很好的解决failureover的问题,即某一台web服务器挂掉后,用户的请求还会被负载到其他的web服务器上,而且由于session也被复制了,这样对用户而言就像是在同一台机器上操作一样。不好的地方就是session复制需要系统资源和网络的开销,也就是所谓的“网络风暴”,尤其是当web服务器多的时候或session里存储的数据量大的时候,这点将会比较的明显。
  session复制本身的操作还是比较复杂的,但是对于服务器来说,配置也算简单,但性能是个很大的问题。当处于一个大于两台服务器的集群中时,复制就比较吃力了。这种方案现在一般不使用了。

3、Nginx的sticky方案。

    其实sticky方案和方案一类似,但是sticky能做到把会话死死的粘滞在其中一台服务器上,算是方案一的补充,可以避免CDN网络下的客户端IP突变。很明显,方案1和方案3都存在failover的问题。

4、方案4,NoSQL的集中存储方案

    基于Redis等NoSQL的session集中存储。这种是目前最流行的方案,早期的方案是用MySQL来存储。但仍然存在以下问题:

(1)redis有单点,并且redis的引入增加了系统复杂度,要解决这个单点就得使用redis集群方案,比如codis。

(2)用户量大的情况下,用来连接redis的类库可能存在瓶颈,比如有部分用户反应jedis性能不稳定,高并发下容易挂。

但是就配置而言,不论是PHP还是Java都相对很简单,例如对于PHP而言,只需要安装predis扩展,在php.ini里配置下session存储方案即可

vi /etc/php.ini
session.save_handler = redis
session.save_path = "tcp://192.168.1.102:6379?timeout=15"

注意注释掉/etc/php-fpm.d/www.conf里session的配置,以免配置被覆盖而无效。

对于Java而言,只需要引入一个jar包(https://github.com/jcoleman/tomcat-redis-session-manager),配置server.xml即可。

    不过,对于tomcat而言,tomcat在启动时就会创建一个session,当会话越多的时候,session也就越多。而session在tomcat中属于重量级对象。一个没有任何内容的空session就需要消耗1.5K的内存存储空间。当然,使用redis都是默认内存足够大。

5、放弃session,使用纯cookies

    纯cookies,不使用session,天然分布式。存在的问题:

(1)cookies需要加解密,性能消耗要考虑,而且不能存太多东西,如果cookies存放了一些复杂的数据时,序列化本身消耗也不少。

(2)对于浏览器而言,每次请求都会带上cookies,包括JS和CSS等请求,浪费宽带,除非部署了CDN或专用服务器。这时就需要为静态文件配置一个独立的域名了。其实这个问题,前面几个方案同样存在。

  另外也可以转用token与openid等方式验证用户。

    我个人所使用的方案是方案5+方案4的结合,即仅使用cookies来存储会话标记,不使用应用服务器本身自带的session方案,对于会话信息,不使用session存储,而是直接存放到Redis中。本质上就是方案4的基础上,自己实现一套session机制。这种实现要看具体的语言而定。对于PHP而言,这种做法是多此一举。而对于Java而言,由于tomcat的session实现比较重量级,这种做法能提高一些性能。针对这种方案,我实现了一个自定义的session管理器,用来替代tomcat的默认session管理器,达到节省内存,提高性能的目的。地址在此:

https://github.com/iminto/tomcat-no-session

    需要注意的是:对于方案5,存在一个问题就是如果应用需要考虑“禁止同时登录”的时候,用cookies的解决方案就麻烦很多了。

      如果有更好的方案,也希望你能提供给我。

© 著作权归作者所有

共有 人打赏支持
南湖船老大
粉丝 679
博文 11
码字总数 10246
作品 0
深圳
其他
session会话-nginx-mysql-tomcat

一、如何保持session会话 目前,为了使web能适应大规模的访问,需要实现应用的集群部署。集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这...

柴鑫旺
2017/09/11
0
0
集群环境下session方案好还是no session方案好

集群环境下,必然需要考虑用户和会话的问题,如果不加处理的话,一旦后端IP轮询切换,session也就断了。所以就有了4种方案。先说下session的问题,tomcat在启动时就会创建一个session,当会话...

南湖船老大
2016/03/04
2.2K
18
Nginx反向代理,负载均衡+Tomcat实现Session共享

Nginx反向代理,负载均衡+Tomcat实现Session共享 防伪码:学而不思则罔,思而不学则殆。 作者:何小帅 博客URL:http://hexiaoshuai.blog.51cto.com 一、如何保持session会话 目前,为了使w...

何小帅
06/26
0
0
分布式session共享常用的几种方式

tomcat session共享常用的几种方式 1、请求精确定位 粘性会话:session sticky 例如基于访问ip的hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器保存了用户的session登...

啃不动地大坚果
06/14
0
0
LVS负载均衡之session解决方案

LVS负载均衡之session解决方案 1. 持久连接是什么? 1.1 在LVS中,持久连接是为了用来保证当来自同一个用户的请求时能够定位到同一台服务器。 2. 为什么会用到持久连接? 2.1 cookie/session...

余二五
2017/11/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中国移动蔡谦:5G传输准备就绪

目前5G已成业界热议话题,在即将到来的万物互联时代,5G是非常关键的技术。且5G相比4G,业务场景多种多样,对5G承载网带来巨大挑战。5G传输,承载先行并不仅仅是一个口号。当前5G承载网的部署...

linux-tao
22分钟前
4
0
维护“修理权”,苹果使用专有软件工具来修复MacBook Pro和iMac Pro

根据上月发给苹果授权服务提供商的一份文件,苹果公司正在使用新的专有软件诊断工具来修复MacBook Pros和iMac Pros,如果不用专有软件工具来修复关键部件,将会导致“系统失效和修复不完整”...

linuxCool
52分钟前
2
0
cacti监控安装

cacti是用PHP实现的一个软件,它用snmp服务获取数据,然后用rrdtool存储和更新数据,并生成图表展示。比较适合用于交换机、路由器的网络监控,插件众多,可图示化显示网络状况。 cacti官方推...

hiwill
今天
4
0
shell特殊符号、cut、sort、uniq、wc、tee、tr、split命令

10月15日任务 8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 cut 命令 cut作用:截取字符串 用法如下:cat /etc/passwd |head -2 |cut -d ...

hhpuppy
今天
4
0
Springboot实现filter拦截token验证和跨域

背景 web验证授权合法的一般分为下面几种 1使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其...

funnymin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部