默认情况下,php的session文件是保存在磁盘文件中。

在php.ini配置文件中的配置项如下:

  session.save_handler = files

  session.save_path = "N;/path"

* 第一个配置项是指定使用files(文件形式)存储session数据。

* 第二个参数指定保存的路径。N表示生成多少级目录(不放到一个目录下,分散到多个磁盘目录中去)

当我们使用php的内置函数session_start()的时候,就是去上面指定的磁盘目录把session数据载入,实际上就是拿类似sess_74dd7807n2mfml49a1i12hkc45的文件。

74dd7807n2mfml49a1i12hkc45就是大家经常说的什么session的id号。

php.ini中还有一个关键配置项,如下:session.name = PHPSESSID

PHPSESSID就是cookie的名称,其实上面一串"74dd7807n2mfml49a1i12hkc45"会保存在一个名为PHPSESSID的cookie中。

第一种办法:把原来存储在服务器磁盘上的session数据存储到客户端的cookie中去。

这样子,就不需要涉及到数据共享了。a客户端请求的时候,原来生成在服务器的数据生成到浏览器的cookie中,根据cookie中的数据识别用户。php由原来的”从本地(也就是服务器)磁盘上读取session数据”转变为”浏览器的cookie中读取数据”,

这样子,在多台php服务器负载均衡的情况下,即便第一秒请求是a服务器,第二秒请求是b服务器,都不需要管哪台服务器了。反正都是读取客户端上的cookie数据。

一般是把session数据按照自己定义的加密规则,加密后后存在cookie中。

弊端:

1.网络请求占用很多。每次请求时,客户端都要通过cookie发送session数据给服务器。

2.浏览器对cookie的大小存在限制。

  Firefox和Safari允许cookie多达4097个字节,包括名(name)、值(value)和等号。

  Opera允许cookie多达4096个字节,包括:名(name)、值(value)和等号。

  Internet Explorer允许cookie多达4095个字节,包括:名(name)、值(value)和等号。

3.要占用很多带宽了(服务器购买带宽是一个很大费用),成本增高。归纳为带宽性能,速度问题。

4.安全问题:把session数据放到客户端,一般session中存的都是重要性数据(帐号、昵称、用户id等),会存在安全问题。

第二种办法:用一种算法(简单理解为规则),也叫做sticky模式(粘性会话模式),同一个用户的访问请求都被派送到同一个服务器上。

用一种算法(简单理解为规则),什么机制下session是保存在哪台服务器下,那么读取的时候就按照这种规则去读取,就能定位到原来的服务器。叫做分发请求,分发到特定的服务器上去,我理解其原理是存session和读session数据保证都在一台服务器操作,就不会需要涉及到共享,具体实现方式是通过约定一种分发机制来实现。

假设是同一个用户user1,每次访问都路由到同一台服务器上,这样即便是在负载均衡的情况下,也能保证每次访问都能读取到session,不需要做session数据共享了。

关键多台server的原因是为负载均衡而做的,那么就得把原来负载均衡的规则假设是—a,现在改为按照session来均衡分发请求的规则—b。

本来负载均衡有一个目的就是:当其中一台机子不可用的时候,会自动分发到可用的机子上去(自动判断现在要请求的机子是否可用)

弊端:

因为某种规则的session都是保存在一台服务器上,比如用户编号是1-200涉及到的session数据保存到a服务器上去。所以只要一台出问题,1-200的用户就无法实现登录了。后面就不可用了(可能想到1-200用户的session服务器用多台进行复制,这感觉很蹩脚,仍然需要用到复制的话,还不如用其他简便的方法)。

第三种办法:做一个中间层,专门来存储所有访问涉及到的session。也就是所有的session都存储在这里。服务器端统一从这里读取session数据。

淘宝的tbsession框架的具体实现,由这个session框架来维护所有网站的session数据。

这种中间层的思想来实现共享,具体的技术方案,我归纳为以下几种:

1、 通过NFS文件共享的方式,多台php服务器共享保存session文件的磁盘。

通过nfs的方式,各个php服务器操作session数据的时候,是读取本地磁盘目录,但实际上是一个共享网络文件。各个php服务器实际上操作的都是同一个目录的文件。

2保存在数据库中,这种方式的扩展性很强,可以随意增加WEB而不受影响。放在数据库里面安全方面好。

写程序要模拟的是,从数据库拿session数据,约定什么情况下数据过期了然后自动清理,这里是指删除数据库中的行保存在文件中的时候,php有垃圾回收机制会去自动清理过期的session文件

有些做法跟这种思想是类似的:比如ecshop、phpcms是把session数据都存储在数据库中去,跟网站的应用级别有关。服务端就是从数据库中拿session的数据。

保存在文件中的时候,则交给了操作系统去控制。一个用户怎么刷新页面,查看其他页面,都只需要读取单个session文件(sess_74dd7807n2mfml49a1i12hkc45)。

3可以将session数据保存在memcached,redis之类内存数据库中,memcached是基于内存存储数据的,性能很高,用户并发量很大的时候尤其合适。

使用内存存储:方便统计在线人数,内存的速度比磁盘访问快、内存数据库系统能够控制内存中的过期数据自动失效(刚好符合session过期需要)。

存储在redis比较理想的选择,存储在数据库中方便存储统计在线人数,那么存储在redis中也实现了这个要求。也可以存储在memcache中。但redis支持的数据类型多。所以用它好点。

使用技术工具复制session数据同步到多台服务器的方案:

使用一些文件同步工具(linux下的rsync),当a服务器中的session数据有更改的时候,就会把这些更改也同步到b,c服务器上去。通过复制的方式,最终a,b,c各个服务器上都拷贝了一份session数据。

弊端:

速度慢。复制数据会出现延迟。比如第一秒访问是a服务器,修改了session数据,负载均衡,可能下一秒访问是b服务器,session数据如果没有被复制到b服务器,则是读取不到session数据的,出现时间上的延迟。这种复制数据要消耗很多网络带宽的。

讨论session共享方案设计的更多相关文章

  1. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  2. 跨应用Session共享

    摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术.本文将详细讨论session的工作机制并且对在Java ...

  3. 用Nginx实现Session共享的均衡负载

    前言 大学三年多,也做个几个网站和APP后端,老是被人问到,如果用户多了服务器会不会挂,总是很尴尬的回答:“哈哈,我们的用户还少,到了服务器撑不住的时候,估计都上市了吧”.说是这么说,但是对于有强迫症 ...

  4. 分布式Session共享(二):tomcat+memcached实现session共享

    一.前言 本文主要测试memcached实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port To ...

  5. 分布式Session共享(一):tomcat+redis实现session共享

    一.前言 本文主要测试redis实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port Tomcat ...

  6. Asp.Net集群中Session共享

    今天遇到了这个问题,于是研究了一下.要解决这个问题,首先就要明白一些Session的机理.Session在服务器是以散列表形式存在的,我们都知道Session是会话级的,每个用户访问都会生成一个Ses ...

  7. Shiro+Redis实现tomcat集群session共享

      一.背景 当我们使用了nginx做项目集群以后,就会出现一个很严重的问题亟待解决,那就是:tomcat集群之间如何实现session共享的问题,如果这个问题不解决,就会出现登陆过后再次请求资源依旧 ...

  8. Windows 环境下分布式跨域Session共享(转)

    出处:http://www.cnblogs.com/stangray/p/3328092.html 为什么还是那句话,在网上找了N篇Session共享,但真正可以直接解决问题的还是没有找到. 一.以下 ...

  9. [转]分布式中使用Redis实现Session共享(二)

    本文转自:http://www.cnblogs.com/yanweidie/p/4678095.html 上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见 ...

随机推荐

  1. 模拟SWPU邮件登录页面

    模拟SWPU邮件登录页面设计流程 一.开发工具准备 本次开发该页面时使用的开发工具为vscode—— 在下载安装完成后,需要下载各类插件——如汉化.通过浏览器打开网页插件等. 二.开发过程 首先,打开 ...

  2. mysql小白系列_06 备份与恢复

    1.使用mydumper工具全库备份. 1)源码编译安装 2)全库备份 2.误操作truncate table gyj_t1;利用mysqldump的备份和binlog日志对表gyj_t1做完全恢复. ...

  3. Java 解决采集UTF-8网页空格变成问号乱码

    http://blog.csdn.net/bob007/article/details/27098875 使用此方法转换后,在列表中看到的正常,但是在详情页的文本框中查看到的就是 了,只好过滤掉所有的 ...

  4. F. Dominant Indices

    题意:求每个点的子树中哪一层节点数最多,如果有节点数最多不唯一,取层数最小的. 题解:dus on tree 基本想法是对每一个节点都构建一个deep数组,然后从底向上更新过来,但是这样空间复杂度和时 ...

  5. 二、$CSS部分

    1.css sprite是什么,有什么优缺点 概念:将多个小图片拼接到一个图片中.通过background-position和元素尺寸调节需要显示的背景图案. 优点: 减少HTTP请求数,极大地提高页 ...

  6. poi--读取不同类型的excel表格

    要想根据不同类型excel表格获取其数据,就要先判断其表格类型 poi-api种方法: getCellType    public int getCellType()        Return th ...

  7. Istio ServiceEntry 引入外部服务

    概念及示例 使用服务入口Service Entry来添加一个入口到 Istio 内部维护的服务注册中心.添加了服务入口后,Envoy 代理可以向服务发送流量,就好像它是网格内部的服务一样.配置服务入口 ...

  8. C#中的List基础用法汇总

    List类是ArrayList类的泛型等效类,该类使用大小可按需动态增加的数组实现IList泛型接口. 泛型的好处:它为使用c#语言编写面向对象程序增加了极大的效力和灵活性.不会强行对值类型进行装箱和 ...

  9. 0418部分HomeWork案例

    /* 月份 输入月份,对应返回该月份的天数 利用switch的穿透性,可将多个case合到一个代码块 */ import java.util.Scanner; class HomeWork5{ pub ...

  10. [Unity2d系列教程] 001.引用外部DLL - C#

    众所周知,Unity可以支持多种语言开发, C#, JS, Boo三种方式的开发, 能够很方便的集成一些外部插件,以便调用现有的动态链接库.学过C#的都知道C#可以生成一个dll供给其他的程序调用.那 ...