已经大半年没有更新博客了,一方面有比博客更重要的事情要做,另外一方面也没有时间来整理知识,所以希望在接下来的日子里面能够多多的写博客来与大家交流

什么是session

session的官方定义是:Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。

说白了session就是一种可以维持服务器端的数据存储技术。session主要有以下的这些特点:

1. session保存的位置是在服务器端

2. session一般来说是要配合cookie使用,如果是浏览器禁用了cookie功能,也就只能够使用URL重写来实现session存储的功能

3. 单纯的使用session来维持用户状态的话,那么当同时登录的用户数量较多的时候,或者存在较多的数量的session会导致查询慢的问题

 本质上:session技术就是一种基于后端有别于数据库的临时存储数据的技术

为什么要有session

主要的一个原因就是HTTP的无状态性

因为HTTP的无状态性,所以我们没有办法在HTTP发送请求的时候知道当前用户的状态,也就是比如说,当前是哪个用户的之类的这种信息,所以这个时候我们需要session来标识当前的状态

seesion的工作原理

接下来,通过一个模拟用户登录的流程图来初步理解session的原理,假设这个时候用户执行登录操作,具体的session工作流程如下:

整个流程大概分成这样的几步:

1. 第一步将本地的cookie中的session标识和用户名,密码带到后台中

2. 第二步后台检测有没有对应的session标识,我们以php为例,那么就是检测有没有接收到对应的PHPSESSID

3. 没有的话直接生成一个新的session。有的话,检测对应的文件是否存在并且有效

3. 失效的话,我们需要清除session然后生成新的session。不失效,使用当前的session

看到这里你可能对session的工作原理有一个初步的理解

session的原理图如下:

session的常见配置

我们这里以PHP为例来讲解一下关于session的配置

首先我们要在PHP的安装目录下面找到php.ini文件,这个文件主要的作用是对PHP进行一些配置,具体以后涉及到再详讲。

1. 设置session存放在cookie中中标识的字段名,php中默认为PHPSESSID

对应的设置为:session.name = PHPSESSID

2. 如果客户端禁用了cookie,可以通过设置session.use_trans_sid来使标识的交互方式从cookie变为url传递

对应的设置为: session.use_trans_sid = 0

3. 设置session的保存位置

对应的设置是session.save_path="D:\phpStudy\PHPTutorial\tmp\tmp"

PHP中session实战

首先我们需要安装wamp或者是phpstudy,具体方式自行百度

为了方便观察session文件的变化,我们需要找到session的保存路径(在php.ini中找到session.save_path),如下:

然后找到所指向的目录,注意一般来说session是使用files的形式来保存的,但是我们也可以根据自己的实际情况进行修改。我们可以在php.ini文件中进行修改和查看。

使用session的第一步,我们要打开session,使用session_start(),然后我们给创建的session添加一个变量,我们假设为demo1,值为default ,代码如下:

<?php
/**
* Created by PhpStorm.
* Date: 2017/12/16
*/
session_start();// 打开session
$_SESSION["demo1"] = "default";
?>

执行效果如下:

打开对应的文件,里面的内容如下:

s:7 表示的是类型为string类型,长度为7个长度的字符串

如果我们对session中的内容进行重新编辑的话,效果如下:

我们观察最近一条的修改日期,我们可以发现就是日期发生了变化,但是文件名没有变化,也就是说,修改session中的内容不会导致文件被新建,而是执行对文件的重新写入操作

 session的销毁

销毁session一般有两种方式,unset和session_destroy,我们先来说说第一种

代码如下:

<?php
/**
* Created by PhpStorm.
* Date: 2017/12/16
*/
session_start();// 打开session
$_SESSION["demo1"] = "default_1";
//session的销毁
unset($_SESSION);
?>

这一个相当于没有删除session文件,但是使得即使有对应的PHPSESSID也无法获取到相应的session

session_destroy()相对来说比较彻底,直接删除对应的session文件

<?php
/**
* Created by PhpStorm.
* Date: 2017/12/16
*/
session_start();// 打开session
$_SESSION["demo1"] = "default_1";
var_dump(session_name());
//session的销毁
session_destroy();
?>

运行的效果如下:

对于个人来说比较推荐使用第二种方法,因为当要销毁session的时候,那么也就意味着session已经失效了,所以这个时候我们把它给删掉才是最好的处理方式,一方面可以减少对硬盘的存储,另外一方面可以相对优化session的查询速度。

好了,这个时候我们应该要设置传递给浏览器端的cookie了,默认是自动传送,但是我们应该要学习的是怎样通过后端设置cookie过去

其中有两个方法与session有关的方法我们需要记住,第一个是session_name(),这个是获取cookie的key值得,第二个是session_id,这个是session的文件名

设置的示例代码:

<?php
/**
* Created by PhpStorm.
* Date: 2017/12/16
*/
session_start();// 打开session
$_SESSION["demo1"] = "default_1";
setCookie(session_name(),session_id(),time()-1000);
?>

在设置cookie的时候,我们为了程序的安全性,我们应该要禁止JS可以对cookie进行重写,所以需要设置HTTP ONLY,具体的设置方法在Php.ini中找到session.cookie_httponly

然后将其的值设置为1或者true即可

除此之外还可以通过setCookie和ini_set()来动态设置HTTPONLY属性

在使用session的时候,虽然会从浏览器把PHPSESSID传给后端,但是这个课程不需要人为的去参与。我们只需要保证HTTPONLY被设置就行了。下面是完整的代码:

<?php
/**
* Created by PhpStorm.
* Date: 2017/12/16
*/
session_start();// 打开session
if ($_SESSION) {
var_dump($_SESSION["demo1"]);
} else {
$_SESSION["demo1"] = "default_" . time();
var_dump($_SESSION["demo1"]);
setCookie(session_name(), session_id(), time(), NULL, NULL, NULL, true);
} ?>
session的一些相关注意事项

 1. 关闭浏览器session同样存在

如果我们没有人为的去设置cookie的生命周期的时候默认关闭浏览器session的状态是无法被保存下来的,因为没有设置cookie的生命周期,默认这个时候cookie为session cookie也就是在会话存在的时候cookie才有效,所以关闭浏览器cookie失效,导致后端拿不到对应的PHPSESSID,所以无法找到对应的session文件

2.  session性能瓶颈怎样解决?

如果是后端存在大量的session的时候,那么这个时候就会出现性能的瓶颈,例如:当后端同时存在有5000个session文件的时候,假设要找的文件是在第4999个,那么也就是说前面至少需要遍历4998次,这样就会浪费过多的时间在后端的循环遍历查找文件中,所以这个时候最有效的方法是使用redis或者mongodb,原理是通过将原本保存在本地的session文件写入到内存中,通过内存换空间的形式来达到提升速度

3. 一般不使用URL重写的方法来传递PHPSESSID

其中主要有两个原因,一个是URL重写方式传递的话会导致URL混乱,影响美观。另一个是增大了用户误操作的几率

更多的session的相关配置请点击这里

更多的一些PHP.ini中session的含义
[Session]
session.save_handler = files #session的存储方式
session.use_cookies= 1 #使用cookies在客户端保存会话
session.use_only_cookies = 1 #去保护URL中传送session id的用户
session.name = PHPSESSID #session名称(默认PHPSESSID)
session.auto_start = 0 #不启用请求自动初始化session
session.cookie_lifetime = 0 #cookie存活时间(0为直至浏览器重启,单位秒)
session.cookie_path = / #cookie的有效路径
session.cookie_domain = #cookie的有效域名
session.cookie_httponly = #httponly标记增加到cookie上(脚本语言无法抓取)
session.serialize_handler = php #PHP标准序列化
 
session.gc_probability =1
session.gc_divisor =1000 #建议设置1000-5000
#概率=session.gc_probability/session.gc_divisor(1/1000)
#页面访问越频繁概率越小
session.gc_maxlifetime =1440 #过期时间(默认24分钟,单位秒)
 
session.bug_compat_42 = off #全局初始化session变量
session.bug_compat_warn = off
session.referer_check = #防止带有ID的外部URL
session.entopy_length = 0 #读取的字节
session.cache_limiter = {nocache,private,pblic} #HTTP缓冲类型
session.cache_expire = 180 #文档过期时间(分钟)
session.use_trans_sid = 1 #trans_sid支持(默认0)
session.hash_function = 0 #hash方法{0:md5(128 bits),1:SHA-1(160 bits)}
session.hash_bits_per_character = 5 #当转换二进制hash数据奥可读形式是,每个字符保留位数
session.save_path = "/var/lib/php/session" #session id存放路径

深度解剖sesssion运行原理的更多相关文章

  1. 深度解剖session运行原理

    已经大半年没有更新博客了,一方面有比博客更重要的事情要做,另外一方面也没有时间来整理知识,所以希望在接下来的日子里面能够多多的写博客来与大家交流 什么是session session的官方定义是:Se ...

  2. ASP.NET Core 运行原理解剖[1]:Hosting

    ASP.NET Core 是新一代的 ASP.NET,第一次出现时代号为 ASP.NET vNext,后来命名为ASP.NET 5,随着它的完善与成熟,最终命名为 ASP.NET Core,表明它不是 ...

  3. ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍

    在上一章中,我们介绍了 ASP.NET Core 的启动过程,主要是对 WebHost 源码的探索.而本文则是对上文的一个补充,更加偏向于实战,详细的介绍一下我们在实际开发中需要对 Hosting 做 ...

  4. ASP.NET Core 运行原理解剖[3]:Middleware-请求管道的构成

    在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 HttpModule 来实现对请求管道事件监 ...

  5. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    HttpContext是ASP.NET中的核心对象,每一个请求都会创建一个对应的HttpContext对象,我们的应用程序便是通过HttpContext对象来获取请求信息,最终生成响应,写回到Http ...

  6. ASP.NET Core 运行原理解剖[5]:Authentication

    在现代应用程序中,认证已不再是简单的将用户凭证保存在浏览器中,而要适应多种场景,如App,WebAPI,第三方登录等等.在 ASP.NET 4.x 时代的Windows认证和Forms认证已无法满足现 ...

  7. C语言深度解剖读书笔记

    开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...

  8. 深度解剖dubbo源码

    -----------学习dubbo源码,能给你带来什么好处?----------- 1.提升SOA的微服务架构设计能力   通过读dubbo源码是一条非常不错的通往SOA架构设计之路,毕竟SOA的服 ...

  9. 前端工具-定制ESLint 插件以及了解ESLint的运行原理

    这篇文章目的是介绍如何创建一个ESLint插件和创建一个ESLint rule,用以帮助我们更深入的理解ESLint的运行原理,并且在有必要时可以根据需求创建出一个完美满足自己需求的Lint规则. 插 ...

随机推荐

  1. IIS 服务无法在此时接受控制信息

    应用程序池无法重新启动,报错:服务无法在此时接受控制信息 解决方法:重启 Credential Manager服务即可

  2. HDU1019 Least Common Multiple(多个数的最小公倍数)

    The least common multiple (LCM) of a set of positive integers is the smallest positive integer which ...

  3. 【转】解决memcached启动失败

    原文:http://chenzhou123520.iteye.com/blog/1925196 linux上启动Memcache报错: 原因一般有两个, 一个是操作系统里确实没有包含该共享库(lib* ...

  4. Python datetime之timedelta

    该函数表示两个时间的间隔 参数可选.默认值都为0:datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minut ...

  5. Spring学习日志之Bean的装配

    Spring容器负责创建应用程序中的bean并通过依赖注入来协调这些对象之间的关系.但是,作为开发人员,要告诉Spring需要创建哪些bean并且如何将其装配在一起.当描述bean如何装配时,Spri ...

  6. asp.net应用发布到IIS无法链接到oracle数据库

    遇到这个问题纠结了好久,试了好多的方法,其中我的问题是,先安装了.net frameword4然后又安装的IIS. 正确方式应该是先安装IIS 然后安装.net framework;且应用程序池没有启 ...

  7. 如何实现websocket服务器-理论篇

    WebSocket 服务器简单来说就是一个遵循特殊协议监听服务器任意端口的tcp应用.搭建一个定制服务器的任务通常会让让人们感到害怕.然而基于实现一个简单的Websocket服务器没有那么麻烦. 一个 ...

  8. Input类型是checkbox时checked属性获取

    记录一下checkbox 的 checked 属性的获取办法,以备忘记: 假如你的一个HTML页中有这么一段代码: <input name="chbRem" id=" ...

  9. 最大流——Dinic算法

    前面花了很长时间弄明白了压入-重标记的各种方法,结果号称是O(V3)的算法测demo的时候居然TLE了一个点,看了题解发现所有人都是用Dinic算法写的,但它的复杂度O(V2E)明显高于前者,具体是怎 ...

  10. tomcat配置虚拟路径保存、访问图片

    一些项目中往往需要上传一些图片文件之类,一般不建议直接保存在数据库内,往往是讲图片等资源保存在服务器的某个文件夹下,传统做法是上传到部署目录下,通过相对路径进行访问.这样当我们系统需要进行升级,进行全 ...