session原理及实现共享
一、session的本质
http协议是无状态的,即你连续訪问某个网页100次和訪问1次对server来说是没有差别对待的,由于它记不住你。
那么,在一些场合,确实须要server记住当前用户怎么办?比方用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入username和password吧,为了解决问题,session的方案就被提了出来,其实它并非什么新技术,并且也不能脱离http协议以及不论什么现有的web技术。
原理非常easy,如果你訪问网页时就像逛澡堂,第一次进去你是没有钥匙的,这个时候你交了钱服务台就分配一把钥匙给你,你走到哪里都要带上,由于这是你身份的唯一标识,接下来你用这把钥匙能够去打开一个专有的储物柜存储你的衣物,游完泳,你再用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,你的这次游泳的过程就是一次session,或者叫做会话,在这个样例中,钥匙就是session的key,而储物柜能够理解为存储用户会话信息的介质。
那么在web server中怎样实现session呢?想必看了上面的样例你会非常easy理解,主要是解决两个问题,一个是钥匙的问题,一个是存储用户信息的问题。对于第一个问题,即什么东西能够让你每次请求都会自己主动带到server呢?假设你比較了解http协议,那么答案一目了然,就是cookie,假设你想为用户建立一次会话,能够在用户授权成功时给他一个cookie,叫做会话id,它当然是唯一的,比方php就会为建立会话的用户默认set一个名为phpsessid,值看起来为一个随机字符串的cookie,假设下次发现用户带了这个cookie,server就知道,哎呀,刚刚这位顾客来了。
剩下的是解决第二个问题,即怎样存储用户的信息,server知道会话id为abc的用户来了,那abc想存储自己的私人信息,比方购物车信息,怎样处理?这个时候能够用内存、也能够用文件,也能够用数据库了,但有个要求是,数据须要用用户的会话id就可以取到,比方php就默认会把会话id为abc的用户会话数据存储到/tmp/phpsess_abc的文件中面,每次读取都要反序列化程序能够理解的数据,写的时候又须要序列化为持久的数据格式。
较好理解的描写叙述:
session被用于表示一个持续的连接状态,在站点訪问中一般指代client浏览器的进程从开启到结束的过程。session事实上就是站点分析的訪问(visits)度量,表示一个訪问的过程。
session的常见实现形式是会话cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,仅仅要关闭浏览器窗体,cookie就消失了。实现机制是当用户发起一个请求的时候,server会检查该请求中是否包括sessionid,假设未包括,则系统会创造一个名为JSESSIONID的输出 cookie返回给浏览器(仅仅放入内存,并不存在硬盘中),并将其以HashTable的形式写到server的内存里面;当已经包括sessionid是,服务端会检查找到与该session相匹配的信息,假设存在则直接使用该sessionid,若不存在则又一次生成新的 session。这里须要注意的是session始终是有服务端创建的,并不是浏览器自己生成的。 可是浏览器的cookie被禁止后session就须要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现。
二、怎样实现session的共享?
首先我们应该明确,为什么要实现共享,假设你的站点是存放在一个机器上,那么是不存在这个问题的,由于会话数据就在这台机器,可是假设你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在client是没有问题的,可是假设用户的两次请求到了两台不同的机器,而它的session数据可能存在当中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。
1.各种web框架早已考虑到这个问题,比方asp.net,是支持通过配置文件改动session的存储介质为sql server的,全部机器的会话数据都从同一个数据库读,就不会存在不一致的问题;
2.以cookie加密的方式保存在client.长处是减轻server端的压力,缺点是受到cookie的限制大小,可能占用一定带宽,由于每次请求会在头部附带一定大小的cookie信息,另外这样的方式在用户禁止使用cookie的情况下无效.
3.server间同步。定时同步各个server的session信息,此方法可能有一定延时,用户体验也不是非常好。
4.php支持把会话数据存储到某台memcacheserver,你也能够手工把session文件存放的文件夹改为nfs网络文件系统,从而实现文件的跨机器共享。
另一个简单的办法能够用于会话信息不会频繁变更的情况,在机器a设置用户会话的时候,把会话数据post到机器b的一个cgi,机器b的cgi把会话数据存下来,这样机器a和b都会有同一份session数据的拷贝。
http协议是无状态的,即你连续訪问某个网页100次和訪问1次对server来说是没有差别对待的,由于它记不住你。
那么,在一些场合,确实须要server记住当前用户怎么办?比方用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入username和password吧,为了解决问题,session的方案就被提了出来,其实它并非什么新技术,并且也不能脱离http协议以及不论什么现有的web技术。
原理非常easy,如果你訪问网页时就像逛澡堂,第一次进去你是没有钥匙的,这个时候你交了钱服务台就分配一把钥匙给你,你走到哪里都要带上,由于这是你身份的唯一标识,接下来你用这把钥匙能够去打开一个专有的储物柜存储你的衣物,游完泳,你再用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,你的这次游泳的过程就是一次session,或者叫做会话,在这个样例中,钥匙就是session的key,而储物柜能够理解为存储用户会话信息的介质。
那么在web server中怎样实现session呢?想必看了上面的样例你会非常easy理解,主要是解决两个问题,一个是钥匙的问题,一个是存储用户信息的问题。对于第一个问题,即什么东西能够让你每次请求都会自己主动带到server呢?假设你比較了解http协议,那么答案一目了然,就是cookie,假设你想为用户建立一次会话,能够在用户授权成功时给他一个cookie,叫做会话id,它当然是唯一的,比方php就会为建立会话的用户默认set一个名为phpsessid,值看起来为一个随机字符串的cookie,假设下次发现用户带了这个cookie,server就知道,哎呀,刚刚这位顾客来了。
剩下的是解决第二个问题,即怎样存储用户的信息,server知道会话id为abc的用户来了,那abc想存储自己的私人信息,比方购物车信息,怎样处理?这个时候能够用内存、也能够用文件,也能够用数据库了,但有个要求是,数据须要用用户的会话id就可以取到,比方php就默认会把会话id为abc的用户会话数据存储到/tmp/phpsess_abc的文件中面,每次读取都要反序列化程序能够理解的数据,写的时候又须要序列化为持久的数据格式。
较好理解的描写叙述:
session被用于表示一个持续的连接状态,在站点訪问中一般指代client浏览器的进程从开启到结束的过程。session事实上就是站点分析的訪问(visits)度量,表示一个訪问的过程。
session的常见实现形式是会话cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,仅仅要关闭浏览器窗体,cookie就消失了。实现机制是当用户发起一个请求的时候,server会检查该请求中是否包括sessionid,假设未包括,则系统会创造一个名为JSESSIONID的输出 cookie返回给浏览器(仅仅放入内存,并不存在硬盘中),并将其以HashTable的形式写到server的内存里面;当已经包括sessionid是,服务端会检查找到与该session相匹配的信息,假设存在则直接使用该sessionid,若不存在则又一次生成新的 session。这里须要注意的是session始终是有服务端创建的,并不是浏览器自己生成的。 可是浏览器的cookie被禁止后session就须要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现。
二、怎样实现session的共享?
首先我们应该明确,为什么要实现共享,假设你的站点是存放在一个机器上,那么是不存在这个问题的,由于会话数据就在这台机器,可是假设你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在client是没有问题的,可是假设用户的两次请求到了两台不同的机器,而它的session数据可能存在当中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。
1.各种web框架早已考虑到这个问题,比方asp.net,是支持通过配置文件改动session的存储介质为sql server的,全部机器的会话数据都从同一个数据库读,就不会存在不一致的问题;
2.以cookie加密的方式保存在client.长处是减轻server端的压力,缺点是受到cookie的限制大小,可能占用一定带宽,由于每次请求会在头部附带一定大小的cookie信息,另外这样的方式在用户禁止使用cookie的情况下无效.
3.server间同步。定时同步各个server的session信息,此方法可能有一定延时,用户体验也不是非常好。
4.php支持把会话数据存储到某台memcacheserver,你也能够手工把session文件存放的文件夹改为nfs网络文件系统,从而实现文件的跨机器共享。
另一个简单的办法能够用于会话信息不会频繁变更的情况,在机器a设置用户会话的时候,把会话数据post到机器b的一个cgi,机器b的cgi把会话数据存下来,这样机器a和b都会有同一份session数据的拷贝。