`
richie.lee
  • 浏览: 29404 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

HttpSession框架

阅读更多

1.问题

众所周知,标准的Servlet API中,有一个HttpSession的接口。本来HTTP协议是无状态的,通过session机制,就能把无状态的变成有状态的。有了session的支持,WEB应该就能够跟踪一个用户的操作状态。在一个WEB应用中,你可以这样使用session

// 取得session对象

HttpSession session = request.getSession();

 

// session中保存用户状态

session.setAttribute(“loginId”, “myName”);

 

// 在另一个请求中,取出session的状态

String myName = (String) session.getAttribute(“loginId”);

如何保存session中的状态?一般的做法,是将session对象保存在内存里,然后用一Session ID来索引。同一时间,会有很多session被保存在服务器的内存里,但每个sessionID都是不一样的。对于Java Servlet,常见的做法是把这个Session ID保存在cookie里。这样一来,凡是cookie值相同的所有的请求,就被看作是在同一个session中的请求。由于内存是有限的,较先进的服务器会把session对象交换到文件中,以确保内存中的session数保持在一个合理的范围内。

为了提高系统扩展性和可用性,我们会使用集群技术 —— 就是一组独立的机器共同运行同一个应用。对用户来讲,集群相当于一台服务器。而实际上,同一用户的两次请求可能被分配到两台不同的服务器上来处理。这样一来,怎样保证两次请求中存取的session值一致呢?

多数的服务器会使用session复制的方法:当session的值被改变时,将它复制到其它机器上。这个方案又有两种具体的实现,一种是广播的方式。这种方式下,任何一台服务器都保存着所有服务器所接受到的session对象。服务器之间随时保持着同步,因而所有服务器都是等同的。可想而知,当访问量增大的时候,这种方式花费在广播session上的带宽有多大,而且随着机器增加,网络负担成指数级上升,不具备高度可扩展性。另一种是TCP-ring的方式,也就是把集群中所有的服务器看成一个环,A->B->C->D->A,首尾相接。把Asession复制到BBsession复制到C,……,以此类推,最后一台服务器的session复制到A。这样,万一A宕机,还有B可以顶上来,用户的session数据不会轻易丢失。但这种方案也有缺点:一是配置复杂;二是每增添/减少一台机器时,ring都需要重新调整,这将成为性能瓶颈;三是要求前端的Load Balancer具有相当强的智能,才能将用户请求分发到正确的机器上。

另一种保存session的思路是,将session保存在单一的数据源中。这个数据源可被集群中所有的机器所共享。这样一来,复制就不是问题了。然而性能成了问题。每个用户请求,都需要访问后端的数据源(很可能是数据库)来存取用户的数据。这种思路的第二个问题是:缺少应用服务厂商的支持 —— 很少有应用服务器支持这种方案,更不用说数据源有很多种(MySQLOracleHsqldb等各种数据库、专用的session server等)了。第三个问题是:数据源成了系统的瓶颈,一但这个数据源崩溃,所有的应用都不可能正常运行了。

综上所述,session看起来很简单,实际上是一个大问题!犹其是对一个访问量极高的大型网站而言。

2.解决方案

2.1.session数据保存在客户端

前面所说的通过复制,或者通过单一数据源,都可以解决集群中分布式session的问题,然而存在前面所说的很多问题。另一种思路,是把session保存在客户端。这样一来,服务器就变成无状态了,就能够做到线性可扩展和极高的可用性。怎么保存呢?目前唯一的方法,恐怕就是cookie了。

Cookie方案也不是完美的,有以下限制:

1.         Cookie数量和长度的限制。每个domain最多只能有20cookie,每个cookie长度不能超过4KB,否则会被截掉。

2.         安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。

3.         有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

虽然有上述缺点,但是对于其优点(极高的扩展性和可用性)来说,就显得微不足道。然而我们仍然要设法回避上述的缺点,方法是:

1.         通过良好的编程,控制保存在cookie中的session对象的大小。

2.         通过加密和安全传输技术(SSL),减少cookie被破解的可能性。

3.         只在cookie中存放不敏感数据,即使被盗也不会有重大损失。

4.         控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie

2.2.session保存在专用的服务器上

前面提到,由于cookie机制本身的限制,我们不可能将所有的数据都放在cookie中,势必要有服务器端的方案来辅助。相比复制的方法,单一的数据源更简单更可靠。我们可以使用数据库来保存这部分session。然而我倾向于使用更廉价、更轻量的存储。事实证明,BerkeleyDB是一种很好的选择。

由于我们只把少量关键的信息保存在服务端,因而这个数据源的压力不会非常大。事实证明,BerkeleyDB在保持良好的可用性的前提下,具有相当高的系统容量,可以高效处理大量的数据请求。

2.3.创建通用的session框架

不是Java Servlet APIsession机制不够灵活,而是多数应用服务器并没有留出足够的余地,来让你自定义session的存储方案。根据上面的讨论,任何一种session方案都有其优缺点。最好的方法是把它们结合起来。例如:结合cookie-based sessionberkeleyDB-based session,就可以解决我们的绝大部分问题。

纵使某个应用服务器提供了对外扩展的接口,可以自定义session的方案,我们也不大可能使用它。为什么呢?因为我们希望保留选择应用服务器软件的自由。

因此,最好的方案,不是在应用服务器上增加什么新功能,而是在WEB应用框架上做手术。一但我们在WEB应用框架中实现了这种灵活的session框架,那么我们的应用可以跑在任何标准的JavaEE应用服务器上。

除此之外,一个好的session框架还应该做到对应用程序透明。具体表现在:

1.         使用标准的HttpSession接口,而不是增加新的API。这样任何WEB应用,都可以轻易在两种不同的session机制之间切换。

2.         应用程序不需要知道session中的对象是被保存到了cookie中还是别的什么地方。

3.         Session框架可以把同一个session中的不同的对象分别保存到不同的地方去,应用程序同样不需要关心这些。例如,把一般信息放到cookie中,关键信息放到berkeleyDB中。甚至同是cookie,也有持久和临时之分,有生命期长短之分。

分享到:
评论
1 楼 zhaoxuqi 2010-11-10  
实力相当高,学习,嘿嘿 

相关推荐

    spring websocket获取httpsession

    在Spring框架中,WebSocket是一种用于实现双向通信的技术,它可以提供实时、低延迟的数据传输,而HttpSession则是HTTP协议中用于跟踪用户会话的一种机制。在Spring 4版本中,我们经常需要结合WebSocket与HttpSession...

    httpsession实现验证码登录小实例

    在实际应用中,通常会配合Ajax或者Web框架(如Spring MVC)的视图解析来实现。 5. **用户输入验证**:用户在看到验证码图片后输入验证码,然后将输入的验证码与服务器端存储的验证码进行比对。如果匹配,登录过程...

    架构探险 从零开始写javaweb框架书上源码

    5. **会话管理**:通过HttpSession对象,读者可以学习如何在用户会话间存储和共享数据。 6. **模板引擎**:用于生成动态HTML的工具,如FreeMarker或JSP,可以减少视图层的复杂性。 7. **异常处理**:理解如何使用...

    java面试题之三大框架题目

    ### Java面试题之三大框架题目详解 #### 一、为何实体类需实现序列化接口? 在探讨这个问题前,我们先了解下序列化的概念及其应用场景。序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。在Java中,...

    用servlet模拟struts_mvc框架

    5. **使用请求参数和会话**:在Servlet中,我们可以通过HttpServletRequest对象获取请求参数,通过HttpSession对象处理会话数据,这些在Struts框架中也是类似的。 在实际项目中,Struts框架提供了更高级的功能,如...

    Spring shiro安全框架介绍

    此外,Shiro还支持通过调用`HttpServletRequest`或`HttpSession`的方法来操作会话,而这些调用最终会被代理给内部的原生会话API。 ### 结论 Spring Shiro安全框架不仅具备强大的功能,而且在易用性和灵活性方面表现...

    架构探险—从零开始写Java Web框架

    4. **会话管理**:学习如何使用HttpSession对象保持用户状态,以及何时使用cookie来辅助会话管理。 5. **路径映射与URL路由**:设计一个优雅的URL路由系统,将HTTP请求映射到对应的处理逻辑,如使用注解或配置文件...

    springMVC+spring+Hibernate框架

    验证成功后,可以将用户信息保存在HttpSession中,实现会话跟踪。此外,Spring的安全模块Spring Security可以用来实现更复杂的权限控制和认证。 总的来说,Spring MVC、Spring和Hibernate的组合提供了一套完整的...

    servletapi.rar_HttpSession jar_Java jar包_javaee.jar_servletAPI

    在Java EE开发中,JAR包通常包含了库、框架或者特定功能的实现。"servletapi.jar"就是这样一个专门针对Servlet API的JAR文件,它包含了Servlet规范定义的类和接口,如Servlet、Filter、Listener等,使得开发者能够...

    架构探险 从零开始写javaweb框架 源代码

    这可能涉及到使用HttpSession对象,或者自定义会话存储和管理机制。 5. **拦截器与过滤器**: 拦截器和过滤器可以对请求和响应进行预处理和后处理。拦截器通常用于AOP(面向切面编程),如权限检查、日志记录等;...

    Java高阶框架面试题-含答案

    - 直接在方法参数中声明`HttpServletRequest request`或`HttpSession session`,SpringMvc会自动注入。 9. **@RequestMapping注解**: - 用在类上,表示类的所有处理方法都以该注解的URL作为前缀。 10. **...

    Tapestry开源框架的详细讲解doc文档(经典)

    通过消除繁琐的“衔接”代码,如解析查询参数、管理HttpSession等,Tapestry帮助开发者专注于业务逻辑,从而降低了代码量,提升了开发效率。 3. **一致性与可复用性**: Tapestry提供了统一的方式来构建Web应用...

    Myeclipse下的网站框架

    在IT行业中,构建网站框架是开发Web应用的关键步骤。MyEclipse是一款强大的集成开发环境(IDE),特别适合Java EE项目的开发,包括JSP(JavaServer Pages)等技术。本篇文章将详细探讨如何在MyEclipse下搭建一个具备...

    mvc框架开发租房网站

    在Java Web中,可以使用HttpSession接口来创建、存储和管理session数据。 至于自定义MVC框架,开发者通常会基于现有的框架技术,如Spring MVC,进行二次开发。主流的框架如Struts、Spring、Hibernate等提供了丰富的...

    抛弃框架的基于纯 Java Servlet 与 JSP的网站系统开发

    6. **会话管理**: 需要手动管理用户的会话状态,可以使用`HttpSession`对象来存储用户状态信息,如登录状态、购物车等。 7. **错误处理与异常捕获**: 编写异常处理代码以确保系统能够优雅地处理错误和异常,同时...

    Strutst2框架的总结

    8. **访问Web元素**:通过实现`SessionAware`接口,Struts2能够注入HttpSession到Action中的Map类型变量,从而方便访问Session数据。 9. **Value Stack**:Value Stack中的值存储在request作用域中,Action中的变量...

    架构探险 从零开始写javaweb框架

    这通常通过HttpSession接口实现,允许在服务器端存储用户信息,跨多个请求保持状态。 5. **模板引擎**:为了生成动态HTML,框架可能集成如FreeMarker或Thymeleaf这样的模板引擎,将数据模型与HTML模板结合,生成...

    Struts框架 架构 应用 演示 ppt

    此外,HttpSession和ServletContext对象分别用于存储session和application级别的共享数据。 1.2 JSP组件 JSP是一种结合了HTML和Java的页面,它的执行过程涉及到JSP容器将JSP转换为Servlet源码,再编译为Servlet类。...

Global site tag (gtag.js) - Google Analytics