1、什么是Session/Cookie?

  用户使用网站的服务,基本上需要浏览器与Web服务器的多次交互。HTTP协议本身是无状态的,当用户的第一次访问请求结束后,后端服务器就无法知道下一次来访问的还是不是上次访问的用户。我们需要基于HTTP协议支持会话状态的机制,这样的机制可以使Web服务器从多次单独的HTTP请求中知道哪些请求是来自哪个会话的。

  Session与Cookie的作用都是为了保持访问用户与后端服务器的交互状态。

1.1、理解Cookie

  Cookie的作用通俗的说就是当一个用户通过HTTP协议访问一个服务器的时候,这个服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器的时候,数据又被完整地带回给服务器。

1.2、理解Session

  Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,这无形地增加了客户端与服务端的数据传输量,而Session的出现正是为了解决这个问题。

  同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个会话标识(SessionId),这个ID是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有一个唯一的ID,客户端只要传回这个ID就行了,这个ID通常是NAME为PHPSESIONID的一个Cookie。在Web服务器上,各个会话独立存储保存不同会话的信息。如果遇到禁用Cookie的情况,一般的做法就是把这个会话标识放到URL的参数中。

2、集群遇到的问题

  从用户端来解释,就是当一个用户第一次访问被负载均衡代理到后端服务器A并登录后,服务器A上保留了用户的登录信息;当用户再次发送请求时,根据负载均衡策略可能被代理到后端不同的服务器,例如服务器B,由于这台服务器B没有用户的登录信息,所以导致用户需要重新登录。这对用户来说是不可忍受的。所以,在实施负载均衡的时候,我们必须考虑Session的问题。

3、解决集群Session共享问题

  在负载均衡中,针对Session的处理,我们一般有以下几种方法:

  (1)、Session 保持

  (2)、Session 复制

  (3)、Session 共享

3.1、会话保持(Session Sticky

  Session保持(会话保持)是我们见到最多的名词之一,通过会话保持,负载均衡进行请求分发的时候保证每个客户端固定的访问到后端的同一台应用服务器。会话保持方案在所有的负载均衡都有对应的实现。而且这是在负载均衡这一层就可以解决Session问题。

  对于Nginx可以选用Session保持的方法实行负载均衡,nginx的upstream目前支持5种方式的分配方式,其中有两种比较通用的Session解决方法,ip_hash和url_hash。注意:后者不是官方模块,需要额外安装。

upstream bakend {
server192.168.0.:;
server192.168.0.:;
ip_hash;
}
  存在问题:
  1)、负载不均衡了:由于使用了Session保持,很显然就无法保证负载绝对的均衡。
  2)、如果这一台Web服务器宕机或者重启了,服务器上的会话数据会丢失,用户需要重新登陆等。
  3)、会话标识是应用层的信息,那么负载均衡器要将同一个会话的请求都保存到同一个Web服务器上的话,就需要进行应用层的解析,这个开销比第四层交换(LVS负载均衡器属于第四层)要大。
  4)、负载均衡器变为一个有状态的节点,要将会话保存到具体的Web服务器的映射。和无状态的节点相比,内存消耗会更大,容灾方面会更麻烦。

3.2、会话复制(Session Replication

  此方案不用再要求负载均衡器保证同一个会话的多次请求必须到同一个Web服务器上了。我们在Web服务器之间增加了会话数据的同步,通过同步就保证了不同Web服务器之间Session数据的一致。

  存在问题:
        1)、同步Session数据造成了网络带宽的开销。只要Session数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大。
        2)、每台Web服务器都要保存所有Session数据,如果整个集群的Session数据很多(很多人同时访问网站)的话,每台机器用于保存Session数据的内容占用会很严重。
 
        这个方案是靠应用容器来完成Session的复制从而解决Session的问题的,应用本身并不关心这个事情。这个方案不适合集群机器数多的场景。如果只有几台机器,用这个方案是可以的。

3.3、会话共享

  Session数据不保存到本机而且存放到一个集中存储的地方,修改Session也是发生在集中存储的地方。Web服务器使用Session从集中存储的地方读取。这样保证了不同Web服务器读取到的Session数据都是一样的。存储Session的具体方式可以是数据库、分布式存储系统等。

  PHP通过两行配置就可以把Session存放在Memcached或者Redis中,当然你要提前配置好他们。

使用memcache存储Session

session.save_handler = memcache
session.save_path = "tcp://192.168.56.11:11211"
使用redis存储Session

session.save_handler = redis
session.save_path ="tcp://localhost:6379"
  存在问题:
        1)、读写Session数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在时延和不稳定性,不过我们的通讯基本都是发生在内网,问题不大。
        2)、如果集中存储Session的机器或者集群有问题,就会影响到我们的应用。
 
        相对于Session Replication,当Web服务器数量比较大、Session数比较多的时候,这个集中存储方案的优势是非常明显的。

分布式集群Session原理及实现共享的更多相关文章

  1. spring-session实现分布式集群session的共享

    前言 HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的.但是我们把应用搭建成分布式的集群,然后利用LVS或Nginx做负载均衡,那么来自同一用户 ...

  2. 分布式集群Session共享 简单多tomcat8+redis的session共享实现

    ; i++) { str = str + session.getAttribute("name" + i) + "<br>"; } response ...

  3. spring-session实现分布式集群session的共享(转)

    原文: https://www.cnblogs.com/youzhibing/p/7348337.html HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保 ...

  4. 基于Ceph分布式集群实现docker跨主机共享数据卷

    上篇文章介绍了如何使用docker部署Ceph分布式存储集群,本篇在此基础之上,介绍如何基于Ceph分布式存储集群实现docker跨主机共享数据卷. 1.环境准备 在原来的环境基础之上,新增一台cen ...

  5. mysql分布式集群实现原理

    做MySQL集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等 有人会问mysql集群,根分表有什么关系吗?虽然它不是实际意义上的分 ...

  6. 采用EaglePHP框架解决分布式集群服务器利用MEMCACHE方式共享SESSION数据的问题

    一.问题起源 稍大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的二级域名,而一个整体性强的网 站,用户系统是统一的,即一套用户名.密码在整个网站的各个模块中都是可以登录 ...

  7. Apache shiro集群实现 (六)分布式集群系统下的高可用session解决方案---Session共享

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  8. 分布式集群环境下,如何实现session共享五(spring-session+redis 实现session共享)

    这是分布式集群环境下,如何实现session共享系列的第五篇.在上一篇:分布式集群环境下,如何实现session共享四(部署项目测试)中,针对nginx不同的负载均衡策略:轮询.ip_hash方式,测 ...

  9. 分布式集群环境下,如何实现session共享四(部署项目测试)

    这是分布式集群环境下,如何实现session共享系列的第四篇.在上一篇:分布式集群环境下,如何实现session共享三(环境搭建)中,已经准备好了相关的环境:tomcat.nginx.redis.本篇 ...

随机推荐

  1. wchat_t与char互转

     C++ Code  1234567891011121314151617181920212223242526   //窄字符转宽字符 void ConvertA2W(wchar_t* the_strw ...

  2. 51、自定义View基础和原理

    一.编写自己的自定义View最简单的自定义View,继承View通过覆盖View的onDraw方法来实现自主显示利用Canvas和paint来绘制显示元素(文字,几何图形等) <com.myvi ...

  3. 转载:定位ARM Hard Fault 的方法

    转载自:http://www.openedv.com/posts/list/25030.htm 1.用Keil的话,可以做如下操作: 先将fault中断函数的内容改为: HardFault_Handl ...

  4. AngularJS 讲解,三 过滤器

    过滤器用来格式化需要展示给用户的数据.AngularJS有很多实用的内置过滤器,同时也提供了方便的途径可以自己创建过滤器. 在HTML中的模板绑定符号{{ }}内通过|符号来调用过滤器.例如:{{va ...

  5. jpa关联映射

    参考:http://www.cnblogs.com/printN/p/6408818.html 官方文档:http://docs.jboss.org/hibernate/orm/5.2/usergui ...

  6. phantomjs学习之网页访问测速

    1.编写loadpage2.js文件: loadpage2.js var page = require('webpage').create(), system = require('system'), ...

  7. Scala学习之For、Function、Lazy(4)

    1.for的使用 for的使用在各种编程语言中是最常见的,这里只是聊聊for在Scala中的表现形式,由于Scala语言是完全面向对象的,所以直接导致for的不同呈现,下面举几个例子说明一下 obje ...

  8. ZooKeeper 基本介绍

    Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储, Zookeeper 作用主要是用来维护和监控存储的数 ...

  9. 【Python之路】第二十一篇--Memcached、Redis

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  10. http://element.eleme.io/#/zh-CN/component/quickstart

    http://element.eleme.io/#/zh-CN/component/quickstart