一 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 的实现原理以及大网站应用应该注意的问题的更多相关文章

  1. session的工作原理

    asp中Session的工作原理:asp的Session是具有进程依赖性的.ASP Session状态存于IIS的进程中,也就是inetinfo.exe这个程序.所以当inetinfo.exe进程崩溃 ...

  2. Spring-Session实现Session共享实现原理以及源码解析

    知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...

  3. Flask中session实现原理

    前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...

  4. Session的原理,大型网站中Session方面应注意什么?

    一.Session和Cookie的区别Session是在服务器端保持会话数据的一种方法(通常用于pc端网站保持登录状态,手机端通常会使用token方式实现),存储在服务端. Cookie是在客户端保持 ...

  5. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

  6. Spring MVC中Session的正确用法<转>

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  7. 【转】Spring MVC中Session的正确用法之我见

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  8. 第三方支付过程中session失效问题

    第三方支付过程中session失效问题 时间 2015-05-13 12:36:23  IT社区推荐资讯 原文  http://itindex.net/detail/53436-session-问题 ...

  9. PHP session的实现原理

    PHP SESSION原理 我们知道,session是在服务器端保持用户会话数据的一种方法,对应的cookie是在客户端保持用户数据.HTTP协议是一种无状态协议,服务器响应完之后就失去了与浏览器的联 ...

随机推荐

  1. Jquery实现全选和取消全选的方法

    <input type="checkbox" id="all" />全选<br /> <input type="chec ...

  2. go语言方法实例

    方便和函数的区别: 方法能给用户定义的类型添加新的行为.方法实际上也是函数,只是在声明时,在关键字func 和方法名之间增加了一个参数. package main import ( "fmt ...

  3. 【转载】Linux中profile、bashrc、bash_profile之间的区别和联系

    如果你想对所有的使用bash的用户修改某个配置并在以后打开的bash都生效的话可以修改这个文件,修改这个文件不用重启,重新打开一个bash即可生效.~/.bash_profile:每个用户都可使用该文 ...

  4. centos 修改ftp目录

    # usermod -d /home/www username // # service vsftpd restart // 重启vsftpd 两步搞定

  5. Python与数据结构[4] -> 散列表[2] -> 开放定址法与再散列的 Python 实现

     开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...

  6. 算法-基数排序(radix sort)

    本文由@呆代待殆原创,转载请注明出处. 简介:这个排序是原来用在卡片排序机上的一个算法,一般用来比较具有多对关键字域的记录,如日期(年月日),通过基数排序我们会依次对年月日这三个关键字进行排序,只要对 ...

  7. POJ 3177 Redundant Paths(边双连通分量)

    [题目链接] http://poj.org/problem?id=3177 [题目大意] 给出一张图,问增加几条边,使得整张图构成双连通分量 [题解] 首先我们对图进行双连通分量缩点, 那么问题就转化 ...

  8. [Contest20180426]校门外的树

    $\newcommand{\align}[1]{\begin{align*}#1\end{align*}}$题意:对于一个排列$p_{1\cdots n}$构造一个图,如果$i\lt j$且$p_i\ ...

  9. 【循环节】 Codeforces Round #401 (Div. 2) A. Shell Game

    容易发现存在循环节. #include<cstdio> using namespace std; int n,x,a[3][6]={{0,1,2,2,1,0},{1,0,0,1,2,2}, ...

  10. Java多线程——ReentrantReadWriteLock源码阅读

    之前讲了<AQS源码阅读>和<ReentrantLock源码阅读>,本次将延续阅读下ReentrantReadWriteLock,建议没看过之前两篇文章的,先大概了解下,有些内 ...