PoEAA笔记-6会话状态

6.1 无状态的价值

        分布式应用中无状态的服务器是指在服务的各请求之间没有保存状态的对象。这样的对象也可以有成员变量,但当你调用无状态服务器上的方法时,这些变量时没有定义的。
        如果在请求之间不需要保存状态,就不用关心时哪个对象来处理某一次请求,如果状态需要保存,则必须找到同一个对象处理。无状态使得我们可以缓存这些对象,用很少的对象就可以处理很多的请求。空闲状态的用户越多,无状态服务器就越有用。可以想象,无状态的服务器对一个高流量的网站来说非常有用,由于内部是无状态的协议,因此使用无状态更加适用。
        很多与客户端交互本身是有状态的,想象一个有成千上万用户的电子商务网站用到的购物车,用户交互包括浏览书籍和购买想买的书,购物车必须在用户的整个会话中保存,实质上这是一个有状态的业务事务,也就说明会话必须是有状态的,如果只是浏览一下不买书就是无状态的,一旦买了,就是有状态的。因此不能避免状态的使用,除非不买书,我们必须决定如何解决这一个问题,好消息是,用无状态的服务器可以实现有状态的服务,有趣的事,我们可能并不愿意这样做。

6.2 会话状态

        购物车的内容就是会话状态,意味着其中的数据只与特定会话有关。这种状态存在于业务事务中,与其他会话及业务事务是分开的。会话状态也区别于我们称之为记录数据的信息,记录数据是长期保存在数据库中的持久化数据,它对所有的会话都可见,会话状态需要提交成为数据库中的记录。
        一个有趣的结果的对一致性的影响,当某个客户在编辑保险单时,当前的保单状态可能时不正确的,客户修改了一个值,并提交,这时系统返回无效值,这些值是会话状态的一部分,但他是无效的。会话状态经常包含这样的无效信息——在处理这些信息时,并没有时时检查他们,而只在业务事务提交时才检查它们。
        会话状态最大的问题出现在处理隔离性的时候,由于很多人在同时操作,因此,在某个用户编辑保险单的时候会发生很多事情,最显然的时两个用户在同时编辑保险单的时候,但并不只有大家都修改时才出问题,假设有两条记录,一条时保险单记录,另一条是客户信息记录,保险单中的风险值与客户信息中的邮政编码有关系。某客户开始编辑保险单,10分钟后又打开了客户信息记录查询邮政编码。然而,在此期间可能有其他用户修改了邮政编码和风险值,导致不一致读。

6.3 存储会话状态的方法

        处理保存会话状态大致分为一下三种:
        客户会话状态,在客户端保存会话状态,使用cookie,串行化数据使其成为Web表单中某个隐藏域,或者把数据放在胖客户端的对象结构中。
        服务器会话状态,在各次请求中把数据放在服务器内存中,通常也可以把数据以序列化的方式持久化起来,对象可以存放在文件系统中或数据源中。
        数据库会话状态,也是在服务端存储的方式。但这种方式把数据分解成多个表和域,并把它保存在数据库中,就像你保存要持久化的数据那样。
        上面几种方法的选择有很多值得考虑的问题。首先,是客户端与服务端的带宽,使用客户端会话意味着每次请求时必须将会话数据通过网络传送。如果数据很少不是什么问题,但数据越多,传输所需的带宽越大,有的应用会用到上兆字节的会话数据。一般情况时将没有压缩的XML数据在客户端和服务端之间传输,即使使用了压缩,也有大量的数据需要传输。
        会话数据必须隔离,大多数情况下,在一个会话中进行的动作比应该会影响其他会话中的动作。
如果系统中有很多用户,应考虑使用集群来提高吞吐率,这种情况下还需要考虑是否需要会话迁移。会话迁移允许一次会话从一台服务器转移到另一台服务器,从而可以由一台服务器处理一个请求,其他服务器处理其他请求。与其相反的事服务器亲和,它要求某一次特定会话的所有请求只能由同一个服务器处理,会话迁移能更好的均衡服务器,特别是在会话很长的情况下,然而用服务器会话状态很难支持会话迁移,因为只有处理会话的那个服务器才能容易的找到会话状态,也有办法处理这个问题——这类方法将模糊数据库会话状态与服务器会话状态之间的界限。
        当服务器决定使用会话状态时,需要把它转换成一种便于快速访问的形式,如果使用服务器会话状态很容易直接访问到会话状态,而如果使用客户会话状态,就需要转换到你想要的格式。如果使用数据库会话状态,就要到数据库中去取信息,这说明美中方法对系统响应性由不同的影响。会话数据的复杂度也会对系统有影响。
        在一个零售系统中,每个会话也许没有那么多数据,但肯定有很多处于空闲状态的用户,因此数据库会话状态能发挥很好的性能。在一个租约系统中,额会有不听的读写数据库的可能,这时服务器会话状态性能较好。
        在B2C应用中经常遇到一个问题:用户不会直接取消会话,而是消失得无影无踪,这时采用客户会话状态最合适,因为可以很容易的忘记那个用户。在其他方式里,必须能够发现那些被取消的会话状态,并将他们清除掉,或者采用某种支持会话超时的系统。好的服务器会话状态实现应能自动支持会话超时。
        与用户取消会话一样,需要考虑系统失效:客户机可能崩溃,服务器可能死掉,网络链接可能突然断掉。数据库会话状态能应付所有这三种情况。服务器会话状态可不可以用取决于会话数据是否放到了持久的存储介质上。客户会话状态在客户机崩溃的时候无能为力,但能应付其他两种情况。
        不要忘记这些模式所需要的开发代价,通常服务器会话状态最容易使用,特别是不需要将会话数据存储到持久介质上时。数据库会话状态客户会话状态通常需要对数据进行解析和转换,所需的额外时间意味着你不能像使用服务器会话状态那样快速的创建出那么多功能,特别是在数据很复杂的时候,复杂的时候,如果对数据到数据库表的映射比较熟悉,乍看好像使用数据库会话状态并不是很复杂,但需要额外花时间来使数据库中的所有所有其他数据与会话数据相隔离。
        我个人倾向于使用服务器会话状态模式,特别是在以下情况下:备忘文件被远程存储以备系统在服务器崩毁之后仍能恢复,我还喜欢使用客户会话状态模式来存放会话标识号和数据量较小的会话,我个人并不喜欢数据库会话状态模式,建议你只将这个模式应用在需要故障恢复和集群的时候,或者无法存储远程备忘,文件的时候,或者不关心会话间数据隔离的时候。

你可能感兴趣的:(笔记,java)