解析 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协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联 ...
随机推荐
- 使用Mybatis做批量插入
最近有个需求,将excel的数据导入的数据库的这个一个操作. 工作主要分为:解析excel,将excel中的数据单条循环插入数据库. 使用框架:mybatis+spring 使用过Mybatis的人都 ...
- php关键字
\b( (a(bstract|nd|rray|s))| (c(a(llable|se|tch)|l(ass|one)|on(st|tinue)))| (d(e(clare|fault)|ie|o))| ...
- HDU 1856 More is better (并查集)
题意: 给你两个数代表这两个人是朋友,朋友的朋友还是朋友~~,问这些人组成的集合里面人最多的是多少... 思路: 属于并查集了,我用的是带路径压缩的,一个集合里面所有元素(除了根节点)的父节点都是根节 ...
- 福州三中集训day3
Day3数据结构,强无敌. 基本讲的是栈,队列,链表,都是些还会的操作,然后接着讲的就比较心凉凉了,先讲了堆,然后是hsah 栈,队列,链表问题都不大,笔记记得都还好,堆就凉凉了. 不会不会不会,没学 ...
- (寒假GYM开黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) author: &qu ...
- 7、Django实战第7天:用form实现登录
Django提供了form对表单进行验证,比如今天要完成的限定登录的时候用户名和密码不能为空,通过这个操作,数据进入到数据库查询之前,我们就可以过滤很多错误,避免不必要的查询. 在users目录下新建 ...
- ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...
- HDU 6313: Hack it
Hack It Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- URAL 2072 Kirill the Gardener 3 (单调DP)
[题目链接] http://acm.timus.ru/problem.aspx?space=1&num=2072 [题目大意] 一个园丁要给一排花浇水,每个花都有一个标号,必须要先浇标号小的, ...
- [BZOJ2753]滑雪与时间胶囊
第一问直接把可以走的边连起来bfs一遍即可 第二问可以用类似kruskal的方法,只不过排序的依据应该变为第一关键字为终点高度(从大到小),第二关键字为边权(从小到大),只排序可以走的边 因为同样高度 ...