session以及分布式服务器session共享
一、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的文件里面,每次读取都要反序列化程序可以理解的数据,写的时候又需要序列化为持久的数据格式。
较好理解的描述:
session被用于表示一个持续的连接状态,在网站访问中一般指代客户端浏览器的进程从开启到结束的过程。session其实就是网站分析的访问(visits)度量,表示一个访问的过程。
session的常见实现形式是会话cookie(session
cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,服务器会检查该请求中是否包含sessionid,如果未包含,则系统会创造一个名为JSESSIONID的输出
cookie返回给浏览器(只放入内存,并不存在硬盘中),并将其以HashTable的形式写到服务器的内存里面;当已经包含sessionid是,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,若不存在则重新生成新的
session。这里需要注意的是session始终是有服务端创建的,并非浏览器自己生成的。 但是浏览器的cookie被禁止后session就需要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现。
二、如何实现session的共享?
目前大多数大型网站的服务器都采用了分布式的部署方式,但是session是在服务器端保存的,如果用户跳转到其他服务器的话,session就会丢失,于是就有了分布式系统的session共享问题。
session共享有很多解决方法,比较常用的如下:
一、以cookie加密的方式保存在客户端.优点是减轻服务器端的压力,缺点是受到cookie的大小限制,可能占用一定带宽,因为每次请求会在头部附带一定大小的cookie信息,另外这种方式在用户禁止使用cookie的情况下无效.
二、服务器间同步。定时同步各个服务器的session信息,此方法可能有一定延时,用户体验也不是很好。
三、以某种媒介共享session信息,比如memcached,NFS等。
1. 通过组播的方式进行集群间的共享,比如tomcat目前就具备这样的功能,优点是web容器自身支持,配置简单,适合小型网站。缺点是当一台机器的上的 session变更后会将变更的数据以组播的形式分发给集群间的所有节点,对网络和所有的web容器都是存在开销。集群越大浪费越严重。不能做到线性的扩 展。
2. 利用NFS等一些共享存储来共享Session数据
大致就是有一台公共的NFS服务器做共享服务器,当然也可以采用数
据库,所有的Web服务器都把session数据写到共享存储介质上,也都要来这台服务器获取session数据,通过这样的方式来实现Session数
据的共享。相比前面组播的方式来说,网络开销较小。缺点是受制于存储设备的依赖,如果存储设备down掉,就无法工作了,要做好主备同步等一些容灾措施。
另外,当访问量过大时,磁盘的IO也是一个非常大的问题。
3.利用Memcache来存储共享Session数据
这可能也是目前
互联网中比较流行的一种用法。所有Web服务器都把Session写入到memcache,也都从memcache来获取。memcache本身就是一个
分布式缓存,便于扩展。网络开销较小,几乎没有IO。性能也更好。缺点,受制于Memcache的容量(除非你有足够内存存储),如果用户量突然增多
cache由于容量的限制会将一些数据挤出缓存,另外memcache故障或重启session会完全丢失掉。
4.完全用cookie
将
用户的session数据全部存放在cookie中,很多大型站点都在这么干。优点是服务器架构也变得简单,每台web服务器都可以很独立。没有网络开销
和对磁盘IO,服务器重启也不会导致数据的丢失。缺点,cookie过于庞大会耗费单位页面的下载时间,所以要尽量保持cookie的精简。
session以及分布式服务器session共享的更多相关文章
- Asp.Net进程外Session(状态服务器Session、数据库Session)
介绍 我们知道,当浏览器关闭,或者网站重启的时候,会话就结束了.即Seesion就丢失了.(当Web.config配置文件改动,哪怕什么内容都不加,仅仅往配置文件中加一个空格都是改we.config变 ...
- 分布式中session共享的解决方案:spring-session
Session是客户端与服务器通讯会话跟踪技术,是服务器与客户端保持整个通讯的会话基本信息.客户端在第一次访问服务器的时候,服务端会响应一个sessionId并且将它存入到本地的Cookie中,在之后 ...
- PHP + Memcache 实现多服务器session共享
很多时候一个完整的系统可能运行在多个服务器上,如果这多个服务器之间需要共享session的话,那么php默认的files保存session的方式就无能为力了.这时我们可以考虑使用memcache 来接 ...
- cookie、session的联系和区别,多台web服务器如何共享session?
cookie在客户端保存状态,session在服务器端保存状态.但是由于在服务器端保存状态的时候,在客户端也需要一个标识,所以session也可能要借助cookie来实现保存标识位的作用.cookie ...
- 负载均衡服务器session共享的解决方案
在ASP.NET的程序中要使用Session对象时,必须确保页面的@page指令中EnableSessionState属性是True或者Readonly,并且在web.config文件中正确的设置了S ...
- [转载]利用memcached在多台服务器之间共享PHP的session数据
原文地址:利用memcached在多台服务器之间共享PHP的session数据作者:a1049709658 最近我的几篇文章都是是最近项目的一点心得^^ 这个项目一开始就设计的"很大&quo ...
- SpringCloud微服务架构分布式组件如何共享session对象
一.简单做一个背景说明1.为说明问题,本文简单微服务架构示例如下 2.组件说明分布式架构,每个组件都是集群或者主备.具体说明如下:zuul service:网关,API调用都走zuul service ...
- Session机制详解及分布式中Session共享解决方案
一.为什么要产生Session http协议本身是无状态的,客户端只需要向服务器请求下载内容,客户端和服务器都不记录彼此的历史信息,每一次请求都是独立的. 为什么是无状态的呢?因为浏览器与服务器是使用 ...
- session和cookie区别,多台WEB服务器如何共享session,禁用COOKIE后SESSION是否可用,为什么?
答:session的运行机制: 用户A访问站点Y,如果站点Y指定了session_start();(以下假设session_start()总是存在)那么会产生一个session_id,这个sessio ...
随机推荐
- echo off
就是说关闭回显 @echo off并不是DOS程序中的,而是DOS批处理中的.当年的DOS,所有操作都用键盘命令来完成,当你每次都要输入相同的命令时,可以把这么多命令存为一个批处理,从此以后,只要运行 ...
- Web 项目遇到的乱码问题
问题代码: jsp: <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...
- OpenGL 多线程共享纹理
1:opengl 多线程共享纹理纹理: //解码时候使用opengl进行绘制,需要构建队列和两个线程,分别用于解码数据并且填充纹理和渲染. 主线程常见两个共享上下文: main() { ⋯⋯⋯⋯ gH ...
- c++官方文档-枚举-联合体-结构体-typedef-using
#include<iostream> #include <new> #include<stdio.h> using namespace std; /** * url ...
- mysql数据库的维护,备份和复制
在数据库运行时维护数据库 执行mysql数据库维护的方法之一就是连接mysql服务器,并告诉它做什么事, 如对myisam数据表进行检查或者修复, 可以使用check table tbname或rep ...
- 微信小程序注册身份证验证
// 校验身份证号 //校验码校验 checkCode: function (val) { var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2])) ...
- ERROR 1222 (21000): The used SELECT statements have a different number of columns :
转自:https://blog.csdn.net/linshichen/article/details/52484224
- CentOS 7 JDK安装
官网: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 1.下载(下图有个错误 ...
- 通过maven 上传jar 到nexus3,cong nexus3下载jar
nexus是一种常见的maven私服软件. 网上介绍的都是nexus2的使用,下面是最新版nexus3的使用方式. 首先需要从官网下载nexus3的包,很卡. 下载好以后解压会有两个文件夹:nexus ...
- 使用root用户,在centos7中安装rabbitMQ
参考地址: https://www.linuxidc.com/Linux/2018-01/150600.htm https://blog.csdn.net/summerhust/article/det ...