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. WPF界面框架的设计

    http://www.cnblogs.com/baihmpgy/p/osgi_muinavtree_fx.html

  2. Django model 改成中文标题

    class Tag(models.Model): title = models.CharField(max_length=30) def __str__(self): return self.titl ...

  3. Ruby on Rails 初次冲浪体验

    为了更好的阅读体验,欢迎訪问 作者博客原文 Rails is a web application development framework written in the Ruby language. ...

  4. jacob操作 office 内部对应代码

    Excel操作  转换 xlAddIn                                 18 Microsoft Office Excel 加载项 xlAddIn8           ...

  5. cocos3.x 接入微信无法调用回调函数onResp的问题

    要想顺利调用必须保证一下几点: 1.WXEntryActivity的包名必须正确,格式为你的APK包名+wxapi.WXEntryActivity(注意:是apk包名,而不是org.cocos2dx. ...

  6. python 之 GIL(线程和进程的应用)

    一.GIL:http://www.tuicool.com/articles/7zIra2r  http://www.zhihu.com/question/23474039 二.线程锁 在threadi ...

  7. C语言数据类型大小

    数据类型大小是由操作系统和编译器共同决定的,但必须满足: short和int至少为16bit:long至少为32bit: short不能超过int,int不能超过long. 在主流编译器中,32位机和 ...

  8. oracle用于判断时间条件为当天的写法(当前日期加一天)

    trunc(sysdate + 1, 'dd')为当前日期加一天: 来自: and wf.start_time between sysdate and trunc(sysdate + 1, 'dd') ...

  9. Spring MVC 框架结构介绍(二)

    Spring MVC框架结构 Spring MVC是围绕DispatcherServlet设计的,DispatcherServlet向处理程序分发各种请求.处理程序默认基于@Controller和@R ...

  10. Django HttpResponse对象详解

    HttpResponse对象 Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数.那么视图函数在处理完相关的逻辑后,也需要返回一个响 ...