为什么有session?

  首先大家知道,http协议是无状态的,即你连续访问某个网页100次和访问1次对服务器来说是没有区别对待的,因为它记不住你。 
  那么,在一些场合,确实需要服务器记住当前用户怎么办?比如用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入用户名和密码吧,为了解决这个问题,session的方案就被提了出来,事实上它并不是什么新技术,而且也不能脱离http协议以及任何现有的web技术。 
  原理很简单,假设你访问网页时就像逛澡堂,第一次进去你是没有钥匙的,这个时候你交了钱服务台就分配一把钥匙给你,你走到哪里都要带上,因为这是你身份的唯一标识,接下来你用这把钥匙可以去打开一个专有的储物柜存储你的衣物,游完泳,你再用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,你的这次游泳的过程就是一次session,或者叫做会话,在这个例子中,钥匙就是session的key,而储物柜可以理解为存储用户会话信息的介质。 
  那么在web server中如何实现session呢?想必看了上面的例子你会很容易理解,主要是解决两个问题,一个是钥匙的问题,一个是存储用户信息的问题。对于第一个问题,即什么东西可以让你每次请求都会自动带到服务器呢?如果你比较了解http协议,那么答案一目了然,就是cookie,如果你想为用户建立一次会话,可以在用户授权成功时给他一个cookie,叫做会话id,它当然是唯一的,比如PHP就会为建立会话的用户默认set一个名为phpsessid,值看起来为一个随机字符串的cookie,如果下次发现用户带了这个cookie,服务器就知道,哎呀,刚刚这位顾客来了。 
  剩下的是解决第二个问题,即如何存储用户的信息,服务器知道会话id为abc的用户来了,那abc想存储自己的私人信息,比如购物车信息,如何处理?这个时候可以用内存、也可以用文件,也可以用数据库了,但有个要求是,数据需要用用户的会话id即可取到,比如php就默认会把会话id为abc的用户会话数据存储到/tmp/phpsess_abc【1】的文件里面,每次读取都要反序列化程序可以理解的数据,写的时候又需要序列化为持久的数据格式。

如何实现session的共享?

  首先我们应该明白,为什么要实现共享,如果你的网站是存放在一个机器上,那么是不存在这个问题的,因为会话数据就在这台机器,但是如果你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。 
  事实上,各种web框架早已考虑到这个问题,比如asp.NET,是支持通过配置文件修改session的存储介质为sql server的,所有机器的会话数据都从同一个数据库读,就不会存在不一致的问题;php支持把会话数据存储到某台memcache服务器,你也可以手工把session文件存放的目录改为nfs网络文件系统,从而实现文件的跨机器共享。 
  还有一个简单的办法可以用于会话信息不会频繁变更的情况,在机器a设置用户会话的时候,把会话数据post到机器b的一个cgi,机器b的cgi把会话数据存下来,这样机器a和b都会有同一份session数据的拷贝。【2】  

SESSION 的数据保存在哪里呢?

PHP中的session存储

  SESSION 的数据保存在哪里呢? 
  当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。 
   默认情况下,PHP.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,而 SESSION 文件保存的目录由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION 数据了。 
   如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path="N;/save_path",N 为分级的级数,save_path 为开始目录。 
   当写入 SESSION 数据的时候,php 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件【3】。读取 SESSION 数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。

Java中的session存储

  sessionid是一个会话的key,浏览器第一次访问服务器会在服务器端生成一个session,有一个sessionid和它对应。tomcat生成的sessionid叫做jsessionid。 
  session在访问tomcat服务器HttpServletRequest的getSession(true)的时候创建,tomcat的ManagerBase类提供创建sessionid的方法:随机数+时间+jvmid。 
  存储在服务器的内存中,tomcat的StandardManager类将session存储在内存中,也可以持久化到file,数据库,memcache,redis等。客户端只保存sessionid到cookie中,而不会保存session,session销毁只能通过invalidate或超时,关掉浏览器并不会关闭session。


  那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。【4】在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session id找到相应的Session,从而再次使用之。


  创建:sessionid第一次产生是在直到某server端程序调用 HttpServletRequest.getSession(true)这样的语句时才被创建。 
  删除:超时;程序调用HttpSession.invalidate();程序关闭。 
  session存放在哪里:服务器端的内存中。【5】不过session可以通过特殊的方式做持久化管理(memcache,redis)。 
  session的id是从哪里来的,sessionID是如何使用的:当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象。 
  session会因为浏览器的关闭而删除吗?不会,session只会通过上面提到的方式去关闭。【6】

博主注

【1】这里需要说明下。博主在Windows下wamp中查看到wamp安装目录下有tmp目录,其中session数据保存的文件以”sess_”作为前缀命名。在CentOS中nginx+php-fpm环境中,配置session的保存路径(在php.ini中配置session.save_path的值,注意这个路径需要Web服务器进程所属用户有权操作-读写操作)后,保存的session文件同样以“sess_”作为前缀命名。 
【2】除了上述提及的方法外,解决session共享问题还有这样一种方式:(实质上并不是通过session的共享来解决的)这里以nginx为例,将用户请求分发到了不同机器上,那么我们只需要固定,同一用户请求分发到同一机器上进行处理,即这一次用户来请求服务器了,那么下一次它再来的时候,同样也请求也被分发到与上一次相同的服务器。这样就确保了同一用户不会因为请求分发到不同机器上而获取不到session数据的问题了。 
【3】后台服务端可以将数据保存在session中,对于php而言,是将数据序列化后保存在文件中,内容如下:

USER|a:5:{s:7:"user_id";s:6:"512071";s:8:"username";s:18:"未命名的昵称";s:5:"phone";s:11:"18888888888";s:9:"last_time";s:19:"2017-06-30 15:45:55";s:6:"is_vip";s:1:"0";}noLoginUser|a:2:{s:10:"session_id";s:40:"captcha_81cd8166e5a84a56605c5903466416da";s:11:"verify_code";s:4:"9626";}
  • 1

【4】从浏览器打开访问了某一个网站,关闭浏览器。这样的操作我们算一次“会话”。所以大部分就会认为用户访问了网站就会产生session ID。实际上不然。例如:在Java中我们需要调用HttpServletRequest的getSession方法创建session。而在PHP中需要session_start()一下,服务器才会将存有session ID的cookie回传回去。否则不会有什么session产生。 
【5】“session存放在哪里:服务器端的内存中。”指的是Tomcat保存session的方式。对于PHP而言是保存在文件中。上述有提及。 
【6】session不会因为浏览器的关闭而删除。但是存有session ID的cookie的默认过期时间是会话级别。也就是用户关闭了浏览器,那么存储在客户端的session ID便会丢失,但是存储在服务器端的session数据并不会被立即删除。从客户端即浏览器看来,好像session被删除了一样(因为我们丢失了session ID,找不到原来的session数据了)。

session是什么,存储在哪里相关推荐

  1. Session id的存储

    Session id的存储方式有以下四种 1.AutoDetect Web.config做相应的配置如下: <system.web>     <sessionState  cooki ...

  2. Cookie、Session、本地存储

    Cookie.Session.本地存储 HTTP协议是无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接,这就意味着服务器无法从连接上跟踪会话,于是出现了Co ...

  3. mysql session 最大值_session 存储最大值

    asp.net Session在web.config中的三种配置方式--详解 这段代码就是设置session在web.config中的存储方式. < sessionState mode=&quo ...

  4. window.open 实现session隔离_InnoDB存储引擎MVCC实现原理

    简单背景介绍 MySQL MySQL是现在最流行的关系型数据库(RDB)的选择, 创建一个应用时,无论是用户数据还是订单数据,使用关系型数据库存储是最可靠稳定的选择,借助RDB提供的可靠性.事务等功能 ...

  5. httpsession mysql,session 的持久化存储

    sessio遇新是直朋能到分览支体调n 的定义: ses用,事少来最差端在事路原们这制码效移,动sion 是一个概念,是一个数据对象,用来存储访问者的朋支不器几事为的时后级功发发来久都这样含制层是请些 ...

  6. spring session通过redis存储,实现session共享

    目录 前言 1 准备工作 1.1 spring框架的jar包 1.2 spring session的相关jar包 2 具体步骤 2.1 创建项目 2.2 spring mvc的配置 2.3 sprin ...

  7. yii2设置session时间_关于 Swoft 2.0 版本用 Redis 存储 session 时配置问题

    Swoft 2.0 在 session 配置上和 1.0 还是有一些不同地方,而关于这些在 github 上完全没有任何说明,甚至连文档也没有.经过逐步梳理源代码(其中要理解他的 "注解&q ...

  8. Session的实现与存储

    [集群中session安全和同步] 使用数据库来保存session,就算服务器宕机了也没事,session照样在. 每次请求都进行数据库读写开销不小(使用内存数据库可以提高性能,宕机就会丢失数据.可供 ...

  9. php存储session更改,php如何修改SESSION的生存存储时间的实例代码_php实例

    PHP session 变量用于存储有关用户会话的信息,或更改用户会话的设置.Session 变量保存的信息是单一用户的,并且可供应用程序中的所有页面使用. PHP Session 变量 当您运行一个 ...

  10. php ?redis,PHP使用Redis存储Session

    对于大访问量的网站来说,会有许多的客户端和服务端建立链接,就会生成许多 Session 文件,由于 Session 文件是存储在硬盘上的,因此每次服务器去读取这些 Session 文件都要经过许多的 ...

最新文章

  1. Paper9:Fast RCNN
  2. SAP MM 事务代码MI31之思考之续集
  3. [转载]jquery 消息插件--仿QQ消息弹出提醒
  4. [java进阶]1.Java读取txt文件和写入txt文件
  5. C++图形着色graph coloring算法(附完整源码)
  6. ThreadLocal的理解
  7. SpringBoot基础篇AOP之基本使用姿势小结
  8. Android近场通信---NFC基础(二)(转)
  9. Python装饰器的实现原理
  10. Versant 对象型数据库
  11. python fileinput处理多文件
  12. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-10.Springboot2.x用户登录拦截器开发实战...
  13. ThinkPHP中使用聚合查询去重求和
  14. 福昕pdf阅读器 去广告版|福昕pdf阅读器Foxit reader 去广告电脑版下载v9.3
  15. latex制作中英文简历(含模板代码)
  16. 中小企业采用云计算的三大障碍
  17. java 模板组件_2-1 模块组件模板目录层级及简单定义
  18. java 判断今天星期几_java判断今天星期几
  19. 敏捷转型行动笔记:用户故事实践
  20. 手机六大操作系统优缺点比较

热门文章

  1. laravel使用artisan报错SQLSTATE[42S02]: Base table or view not found: 1146
  2. [0418] 程序设计实训小结(更新1420)
  3. eclipse data source explorer 编辑触发器
  4. UIView用户事件响应
  5. C#读写XML的两种一般方式
  6. vim的安装以及配置
  7. Java开发笔记(一百二十七)Swing的标签
  8. MFC防止进程重复建立
  9. 《移动平台开发实践》第1周作业
  10. day16 Python 类的继承关系