解析 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协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联 ...
随机推荐
- thinkphp5.0配置nginx重写规则
我的centeros7.3系统,单主机实例: vi /usr/local/nginx/conf/nginx.conf 在如图红框位置加入以下代码(图片是截取的,截取部分上方还有其他的默认配置代码,代码 ...
- webpack + react 前端工程化实践和暂不极致优化
技术结构 webpack + react + react-router 功能实现 关于打包 1.基于react-router的自定义打包code split.2.分包异步按需加载.3.CommonsC ...
- EasyUI中combobox的代码实例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Codeforces 1023 A.Single Wildcard Pattern Matching-匹配字符 (Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Fi)
Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Patter ...
- HDU 3342 拓扑排序模板
Legal or Not Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDU1213 How Many Tables (并查集)
题目大意: 有一个人要过生日了,请他的朋友来吃饭,但是他的朋友互相认识的才能坐在一起,朋友的编号从1 ~ n,输入的两个数代表着这两个人互相认识(如果1和2认识,2和3认识,那么1和3也就认识了).问 ...
- hdu6127
hdu6127 题意 二维平面上存在一些点,每个点都有权值,任意两点组成的线段的权值为这两点权值的乘积,选定一条经过原点的直线,问怎样使得它经过的线段的权值之和最大. 分析 题目等价于用一条直线将平面 ...
- [CF98E]Help Shrek and Donkey
题意:A和B两个卡牌大师玩游戏,A有$n$张牌,B有$m$张牌,桌上有$1$张牌,这$n+m+1$张牌互不相同且A和B都知道这些牌里有什么牌(但他们互相不知道对方有什么牌,两个人也都不知道桌上的那张牌 ...
- 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll
http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...
- UILabel设置行间距
UILabel设置行间距: NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWi ...