解析 PHP 中 session 的实现原理以及大网站应用应该注意的问题
一 PHP SESSION原理
session 是在服务器端保持用户会话数据的一种方法,而 cookie 是在客户端保持用户数据。HTTP 协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联系。那么,服务器是如何记住众多用户的会话数据呢?
首先要将客户端和服务器端建立一对一联系,每个客户端都得有一个唯一标识,这样服务器才能识别出来。建立唯一标识的方法有两种:cookie 或者通过 GET 方式指定。默认配置的 PHP 使用 session 的时候会建立一个名叫 "PHPSESSID" 的 cookie(可以通过 php.ini 修改 session.name 值指定),如果客户端禁用 cookie ,也可以指定通过 GET 方式把 session id 传到服务器(修改 php.ini 中 session.use_trans_sid 等参数)。
查看服务器端 /tmp 目录(在不修改 PHP 配置的情况下)会发现很多类似 sess_0fb45ob06s3ictc5qp98frvjl6 这样的文件,这个其实就是 session id "0fb45ob06s3ictc5qp98frvjl6" 对应的数据。真相就在这里,客户端将 session id 传递到服务器,服务器根据 session id 找到对应的文件,读取的时候对文件内容进行反序列化得到 session 的值,而保存的时候先序列化再写入。
事实就是这样,所以如果服务器不支持 session 或者你想自定义 session,通过 PHP 的 uniqid 生成永不重复的 session id,然后找个地方存储 session 的内容即可。
二 使用 SESSION 之前为什么必须先执行 session_start()?
了解 session 的原理之后,所谓的 session 其实就是客户端一个 session id 对应服务器端一个 session file。新建 session 之前执行 session_start() 是告诉服务器要接收一个cookie 以及准备好 session 文件,要不然 session 内容怎么存;读取 session 之前执行 session_start() 是告诉服务器,赶紧根据 session id 把 session 文件反序列化。
只有一个 session 函数可以在 session_start() 之前执行,session_name():读取或指定 session 名称(比如默认的就是 "PHPSESSID"),这个当然要在 session_start 之前执行。
三 SESSION影响系统性能
session 在大访问量网站上确实影响系统性能,影响性能的原因之一由文件系统设计造成,在同一个目录下超过10000个文件时,文件的定位将非常耗时,PHP支持 session 目录hash,可以通过修改 php.ini 中 session.save_path = “2;/path/to/session/dir”,那么 session 将存储在两级子目录中,每个目录有16个子目录[0~f],不过 PHP session 不支持创建目录,需要事先把那么些目录创建好。
还有一个问题就是小文件的效率问题,一般 session 数据都不会太大(1~2K),如果有大量这样1~2K 的文件在磁盘上,IO 效率肯定会很差。
其实还有很多中存储 session 的方式,可以通过 php -i|grep "Registered save handlers" 查看,比如 Registered save handlers => files user sqlite eaccelerator 可以通过文件、用户、sqlite、eaccelerator来存,如果服务器装了 memcached,还有 mmcache 的选项。当然还有很多,比如 MySQL、PostgreSQL 等等,都是不错的选择。
四 SESSION的同步
前端可能有很多台服务器,用户在A服务器上登录了,种下了 session 信息,然后访问网站的某些页面可能会跳到 B 服务器上去了,如果这个时候 B 服务器上没有 session 信息又没有做特殊处理,可能就会出问题了。
session 同步有很多种,如果你是存储在 memcached 或者 MySQL 中,那就很容易了,指定到同样的位置即可,如果是文件形式的,你可以用 NFS 统一存储。
还有一种方式是通过加密的 cookie 来实现,用户在A服务器上登录成功,在用户的浏览器上种上一个加密的 cookie,当用户访问B服务器时,检查有无 session,如果有当然没问题,如果没有,就去检验 cookie 是否有效,cookie 有效的话就在 B 服务器上重建 session。这种方法其实很有用,如果网站有很多个子频道,服务器也不在一个机房,session 没办法同步又想做统一登录那就太有用了。
当然还有一种方法就是在负载均衡那一层保持会话,把访问者绑定在某个服务器上,那么所有访问都在那个服务器上就不需要 session 同步了。
解析 PHP 中 session 的实现原理以及大网站应用应该注意的问题的更多相关文章
- session的工作原理
asp中Session的工作原理:asp的Session是具有进程依赖性的.ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序.所以当inetinfo.exe进程崩溃 ...
- Spring-Session实现Session共享实现原理以及源码解析
知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...
- Flask中session实现原理
前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...
- Session的原理,大型网站中Session方面应注意什么?
一.Session和Cookie的区别Session是在服务器端保持会话数据的一种方法(通常用于pc端网站保持登录状态,手机端通常会使用token方式实现),存储在服务端. Cookie是在客户端保持 ...
- 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)
简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...
- Spring MVC中Session的正确用法<转>
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- 【转】Spring MVC中Session的正确用法之我见
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- 第三方支付过程中session失效问题
第三方支付过程中session失效问题 时间 2015-05-13 12:36:23 IT社区推荐资讯 原文 http://itindex.net/detail/53436-session-问题 ...
- PHP session的实现原理
PHP SESSION原理 我们知道,session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据.HTTP协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联 ...
随机推荐
- python2和python3中的编码问题
开始拾起python,准备使用python3, 造轮子的过程中遇到了编码的问题,又看了一下python3和python2相比变化的部分. 首先说个概念: unicode:在本文中表示用4byte表示的 ...
- POJ1861 Network(Kruskal)(并查集)
Network Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16047 Accepted: 6362 Spec ...
- 33、Django实战第33天:我的消息
1.编辑usercenter-message.html继承usercenter-base.html 2.编辑users.views.py ... from operation.models impor ...
- POJ 3494 Largest Submatrix of All 1’s(最大子图形)
[题目链接] http://poj.org/problem?id=3494 [题目大意] 在01矩阵中求最大全1子矩形 [题解] 在处理每个点的时候,继承上一个点等高度下的左右最大扩展, 计算在该层的 ...
- POJ 2482 Stars in Your Window(扫描线+线段树)
[题目链接] http://poj.org/problem?id=2482 [题目大意] 给出一些点的二维坐标和权值,求用一个长H,宽W的矩形能框住的最大权值之和, 在矩形边缘的点不计算在内 [题解] ...
- 【树状数组】Gym - 101147J - Whistle's New Car
题意就是对每个点i,统计在其子树内(不含自身),且depj-depi<=xj的点有多少个. 把点分别按照dep-x和dep进行排序,离线处理, 每次把dep-x小于等于当前dep值的点插入树状数 ...
- 【点分治】【乘法逆元】hdu4812 D Tree
思路比较裸,但是要把答案存到哈希表里面,这里需要一定技巧,否则会被K=1且点权全是1的数据卡飞.预处理乘法逆元.TLE了一天.换了种点分治的姿势…… #pragma comment(linker,&q ...
- python 实现汉诺塔问题
代码如下: def hano(n,x,y,z): if n==1: print(x,"->",z) else: #将n-1个盘子从x->y hano(n-1,x,z,y ...
- 51单片机软件I2C驱动中的CY
做一个MSP430的项目,虽然430内部有硬件I2C的模块,略难,准备直接移植51的..碰到一句代码 dat <<= 1; //移出数据的最高位 pSDA = CY; //送数据口 dig ...
- Android UI 统一修改Button控件的样式,以及其它系统控件的默认样式
先介绍下修改原理:首先打开位于android.widget包下面的Button.java文件,这里有一句关键的代码如下: public Button(Context context, Attribut ...