上海网站建设网页设,导航类主题 wordpress,佛山做企业网站的公司,广州seo网站公司session是web开发里一个重要的概念#xff0c;在大多数web应用里session都是被当做现成的东西#xff0c;拿来就直接用#xff0c;但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求#xff0c;当碰到这样的情况时候我们需要更加深入的理解session的机制在大多数web应用里session都是被当做现成的东西拿来就直接用但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求当碰到这样的情况时候我们需要更加深入的理解session的机制本文将梳理下session的相关知识为设计可替代web容器自带的session机制打个基础。 1.1 session的概念 在计算机专业术语里session是指一个终端用户与交互系统进行通信的时间间隔通常指从注册入系统到注销系统之间所经过的时间以及如果需要的话可能还有一定操作空间。 具体到web应用里的session大家都做过web开发这里我就先不提出web里session的定义先和大伙讲下和session相关的技术背景。 早期的web应用或者说早期的网站都是一种处理静态资源的网站功能主要是查看文档看看图片而现在的web应用和早期的差别已经很大互联网的网站更准确的定义应该是互联网软件即网站就是软件网站所代表的软件和早期软件的定义是不一样的早期的软件都是在单机环境下运行而互联网的普及让软件和网络技术融合在一起这就要求网站所代表的软件应该要有一个对事务处理的记忆功能事务处理的记忆功能就是我们常说的要有状态。而实现web应用技术的核心http协议是一个无状态的协议http这种设计也许是历史遗留问题也许无状态的http是最简单也是最有效的通讯方式但是当网站成为软件后状态的保持就是一个很重要的功能。 因此在web应用开发里就出现了保持http链接状态的技术一个是cookie技术另一种是session技术。 cookie技术是客户端的解决方案当然随着html5的出现比cookie更为强劲和安全的技术出现了但是鉴于html5的普及度不够就不做本文讨论的内容了Cookie就是由服务器发给客户端的特殊信息而这些信息以文本文件的方式存放在客户端然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。让我们说得更具体一些当用户使用浏览器访问一个支持Cookie的网站的时候用户会提供包括用户名在内的个人信息并且提交至服务器接着服务器在向客户端回传相应的超文本的同时也会发回这些个人信息当然这些信息并不是存放在HTTP响应体Response Body中的而是存放于HTTP响应头Response Header当客户端浏览器接收到来自服务器的响应之后浏览器会将这些信息存放在一个统一的位置对于Windows操作系统而言我们可以从 [系统盘]:\Documents and Settings\[用户名]\Cookies目录中找到存储的Cookie自此客户端再向服务器发送请求的时候都会把相应的Cookie再次发回至服务器。而这次Cookie信息则存放在HTTP请求头Request Header了。有了Cookie这样的技术实现服务器在接收到来自客户端浏览器的请求之后就能够通过分析存放于请求头的Cookie得到客户端特有的信息从而动态生成与该客户端相对应的内容。通常我们可以从很多网站的登录界面中看到“请记住我”这样的选项如果你勾选了它之后再登录那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了而这个功能就是通过Cookie实现的。 session技术则是服务端的解决方案它是通过服务器来保持状态的。由于Session这个词汇包含的语义很多因此需要在这里明确一下 Session的含义。首先我们通常都会把Session翻译成会话因此我们可以把客户端浏览器与服务器之间一系列交互的动作称为一个 Session。从这个语义出发我们会提到Session持续的时间会提到在Session过程中进行了什么操作等等其次Session指的是服务器端为客户端所开辟的存储空间在其中保存的信息就是用于保持状态。从这个语义出发我们则会提到往Session中存放什么内容如何根据键值从 Session中获取匹配的内容等。要使用Session第一步当然是创建Session了。那么Session在何时创建呢当然还是在服务器端程序运行的过程中创建的不同语言实现的应用程序有不同创建Session的方法而在Java中是通过调用HttpServletRequest的getSession方法使用true作为参数创建的。在创建了Session的同时服务器会为该Session生成唯一的Session id而这个Session id在随后的请求中会被用来重新获得已经创建的Session在Session被创建之后就可以调用Session相关的方法往Session中增加内容了而这些内容只会保存在服务器中发到客户端的只有Session id当客户端再次发送请求的时候会将这个Session id带上服务器接受到请求之后就会依据Session id找到相应的Session从而再次使用之。正式这样一个过程用户的状态也就得以保持了。 由此我们可以得出session是解决http协议无状态问题的服务端解决方案它能让客户端和服务端一系列交互动作变成一个完整的事务能使网站变成一个真正意义上的软件。 1.2 cookie与session的关系 cookie和session的方案虽然分别属于客户端和服务端但是服务端的session的实现对客户端的cookie有依赖关系的上面我讲到服务端执行session机制时候会生成session的id值这个id值会发送给客户端客户端每次请求都会把这个id值放到http请求的头部发送给服务端而这个id值在客户端会保存下来保存的容器就是cookie因此当我们完全禁掉浏览器的cookie的时候服务端的session也会不能正常使用注意有些资料说ASP解决这个问题当浏览器的cookie被禁掉服务端的session任然可以正常使用ASP我没试验过但是对于网络上很多用php和jsp编写的网站我发现禁掉cookie网站的session都无法正常的访问 1.3 session实现的原理 java的web容器都实现了session机制实现的逻辑思想都是一致的但是具体方案可能会存在一定差异这里我以tomcat容器为例探讨下session实现的机制。 下图是tomcat源码里session实现 实现包的路径是org.apache.catalina.sessiontomcat对外提供session调用的接口不在这个实现包里对外接口是在包javax.servlet.http下的HttpSession而实现包里的StandardSession是tomcat提供的标准实现当然对外tomcat不希望用户直接操作StandardSession而是提供了一个StandardSessionFacade类tomcat容器里具体操作session的组件是servlet而servlet操作session是通过StandardSessionFacade进行的这样就可以防止程序员直接操作StandardSession所带来的安全问题。(StandardSessionFacade使用了设计模式里的Façade外观模式外观模式能让不同逻辑层的组件进行解耦)。 实现类里有Manager的类是用来管理session的工具类它负责创建和销毁session对象其中ManagerBase是所有session管理工具类的基类它是一个抽象类所有具体实现session管理功能的类都要继承这个类该类有一个受保护的方法该方法就是创建sessionId值的方法tomcat的session的id值生成的机制是一个随机数加时间加上jvm的id值jvm的id值会根据服务器的硬件信息计算得来因此不同jvm的id值都是唯一的StandardManager类是tomcat容器里默认的session管理实现类它会将session的信息存储到web容器所在服务器的内存里。PersistentManagerBase也是继承ManagerBase类它是所有持久化存储session信息的基类PersistentManager继承了PersistentManagerBase但是这个类只是多了一个静态变量和一个getName方法目前看来意义不大对于持久化存储sessiontomcat还提供了StoreBase的抽象类它是所有持久化存储session的基类另外tomcat还给出了文件存储FileStore和数据存储JDBCStore两个实现。 1.4 在实际运用中session所带来的问题 由上面所描述的session实现机制我们会发现为了弥补http协议的无状态的特点服务端会占用一定的内存和cpu用来存储和处理session计算的开销这也就是tomcat这个的web容器的并发连接那么低tomcat官方文档里默认的连接数是200原因之一。因此很多java语言编写的网站在生产环境里web容器之前会加一个静态资源服务器例如apache服务器或nginx服务器静态资源服务器没有解决http无状态问题的功能因此部署静态资源的服务器也就不会让出内存或cpu计算资源专门去处理像session这样的功能这些内存和cpu资源可以更有效的处理每个http请求因此静态资源服务器的并发连接数更高所以我们可以让那些没有状态保持要求的请求直接在静态服务器里处理而要进行状态保持的请求则在java的web容器里进行处理这样能更好的提升网站的效率。 当下的互联网网站为了提高网站安全性和并发量服务端的部署的服务器的数量往往是大于或等于两台多台服务器对外提供的服务是等价的但是不同的服务器上面肯定会有不同的web容器由上面的讲述我们知道session的实现机制都是web容器里内部机制这就导致一个web容器里所生成的session的id值是不同的因此当一个请求到了A服务器浏览器得到响应后客户端存下的是A服务器上所生成的session的id当在另一个请求分发到了B服务器B服务器上的web容器是不能识别这个session的id值更不会有这个sessionID所对应记录下来的信息这个时候就需要两个不同web容器之间进行session的同步。Tomcat容器有一个官方的解决方案就是使用apachetomcatmod_jk方案当一个web容器里session的信息发生变化后该web容器会向另一个web容器进行广播另一个web收到广播后将session信息同步到自己的容器里这个过程是十分消耗系统资源当访问量增加会严重影响到网站的效率和稳定性。 我现在所做的网站里有一个解决方案当用户请求网站的时候会先将请求发送给硬件的负载均衡设备该设备可以截获客户端发送过来的session的id值然后我们根据这个id值找到产生这个session的服务器将请求直接发送给这台服务器。这种解决方案看起来解决了session共享问题其实结果是将集群系统最终变回了单点系统如果处理请求的web容器挂掉了那么用户的相关会话操作也就废掉了。此外这种做法也干扰了负载均衡服务器的负载均衡的计算让请求的分发并不是公平的。 一般大型互联公司的网站都是有一个个独立的频道所组成的例如我们常用的百度会有百度搜索百度音乐百度百科等等我相信他们不会把这些不同频道都给一个开发团队完成应该每个频道都是一个独立开发团队因为每个频道的应用的都是独立的web应用那么就存在一个跨站点的session同步的问题跨站点的登录可以使用单点登录的SSO的解决方案但是不管什么解决方案跨站点的session共享任然是逃避不了的问题。 1.5 解决session相关问题的技术方案 由上所述session一共有两个问题需要解决 1) session的存储应该独立于web容器也要独立于部署web容器的服务器 2如何进行高效的session同步。 在讲到解决这些问题之前我们首先要考虑下session如何存储才是高效是存在内存、文件还是数据库了文件和数据库的存储方式都是将session的数据固化到硬盘上操作硬盘的方式就是IOIO操作的效率是远远低于操作内存的数据因此文件和数据库存储方式是不可取的所以将session数据存储到内存是最佳的选择。因此最好的解决方案就是使用分布式缓存技术例如memcached和redis将session信息的存储独立出来也是解决session同步问题的方法。 Tomcat的session同步也有使用memcache的解决方案大家可以参加下面的文章 http://blog.sina.com.cn/s/blog_5376c71901017bqx.html 但是该方案只是解决了同步问题session机制任然和web容器紧耦合我们需要一个高效、可扩展的解决方案那么我们就应该不是简单的把session独立出来存储而是设计一个完全独立的session机制它既能给每个web应用提供session的功能又可以实现session同步下面是一篇用zookeeper实现的分布式session方案 http://www.open-open.com/lib/view/open1378556537303.html 好了写完了今天只是简单剖析下session机制以后有机会我拿出一套最好的独立session设计机制方案来的。转载于:https://www.cnblogs.com/kabi/p/6703361.html