有关“无状态“的理解

来源:互联网 发布:算法与程序的关系 编辑:程序博客网 时间:2024/05/22 17:16

一、什么是无状态?

http无状态还是web应用无状态?

我们通常说的web应用程序的无状态性的含义是什么呢?

直观的说,“每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况”这句话的含义是指在说明,采用http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,也不会因为加入cookies、session机制而变成有状态的。

这种前后因果关系:“我们要实现的是一种web应用,实现这种应用的协议我们选择了http这种本质上是无状态的通信协议。但是事实上,我们需要我们的web应用是有状态的。所以我们加入了cookies、session等机制去实现由状态的web应用”。所以我们可以这么理解:Web应用=http协议+sessioncookies等状态机制+其他辅助的机制。

 

我们做一个网络应用,需要使用网络协议。其实按照原理上讲,标准的TCP/IP协议提供给我们的网络层协议(FTP, HTTP)不能直接的被称为应用,因为在实现某种可用的、直接面向用户的应用的时候(如web应用,人们可以上网),只有http协议还是不够的。所以我们可以这么理解。网络标准协议分层中提供给我们的应用层协议,它更像是一种分类。自然界的应用可能是无穷尽的种类,但是根据他们的特点、传输的特色,标准的网络协议在传输层(通用网络协议)的基础上封装出若干种面向不同种类网络应用的协议。某种角度上讲,我们想要实现某种可用的网络应用,直接使用网络协议的传输层给我们提供的接口就可以了(也就是socket接口),但是有时候,这种方式是有些麻烦的,所以我们还是根据你要实现的web应用,在已有的标准协议中提供的面向应用分类的协议中进行选择。这样可以免去那些繁琐的、通用的工作。可以看到,我们实际生活中的有关网络的应用程序,与标准的网络通信协议提供给我们的应用层协议是没有绝对的对应关系。所以标准的网络通信协议给我们提供的应用层协议,只是提供给我的一种“建议的”分类。建议你:“如果你要实现这样的应用,你可以直接使用这个封装协议,而不是socket接口”。

 

(4)HTTP是无状态的,它的底层协议是由状态的TCP但是HTTP的一次完整协议动作,里面是使用有状态的TCP协议来完成的。而每次协议动作之间没有任何关系。例如:第7次请求HTTP协议包,并不知道,这个包是为了什么?它或许是因为上次没有请求成功而重传,或许是上次的后续请求,或许是其他的,这些HTTP自身都不知道。

(5) www应用,但是很多时候,www应用是需要HTTP动作之间是有关联的,那就是使应用有状态。这样才能提供给用户最好的用户体验。

于是,问题就来了,为什么当初HTTP会设计成无状态的,既然现在我们所需要的www应用是有状态的,为什么给他提供的这样的底层协议是无状态的。我想这个问题,可以从历史的角度去思考。在www应用还很简单的时候,这个应用只是被用来浏览内容。如果只是浏览内容的话,无状态的协议已经够了,这样实现可以减轻实现的负担,因为有状态的协议实现起来代价相对来说是很高的(要维护状态,根据状态来处理情况,这就是为什么建议你可以不用session的时候就不用,因为服务器要给你负担起很多的东西,例如内存空间啊)。好,

 

现在看来,似乎www应用是大部分需要状态了,那么是否我们就应该改变这个协议来让他变成一个有状态的协议呢?从这个角度上讲,我认为是不应该的。而web应用中,用户可能访问一个页面后,在那个页面上逗留很久才跳转到另外一个页面,如果你需要我们在这两个页面(两个http请求应答)之间维持状态,是非常代价高的。其次,历史让http无状态,而应用需求对http提出有状态的要求,按照软件领域的通常做法是,保持历史遗留的经验(不再http协议本质上作太大的改动),兼容过去的软件。http上再加上一层来实现我们的目的(“再加上一层,你能做任何事”)。这一层,就是cookies,就是session等。最后总结,http协议仍然保持无状态,其充分的理由,并且,想要基于http协议的web应用变得有状态,实现起来并不麻烦。web应用都有哪些方法来让应用有状态于是就引出了,在http协议的基础上,web应用引入cookies, session, application。这样的东西来保持web应用之间的状态。可知,cookies,session,application都不是标准协议,但是各种网络应用提供商,实现语言、web容器等,都默认支持它。当然这种支持与对网络标准协议的支持是不同的,标准协议规定的接口,而这种机制,只是规定了思想。有人将web应用中有无状态的情况,比着顾客逛商店的情景。顾客:浏览器访问方;商店:web服务器;一次购买:一次http访问我们知道,上一次顾客购买,并不代表顾客下一个小时一定会买(当然也不能代表不会)。也就是说同一个顾客的不同购买之间的关系是不定的。所以说实在的,这种情况下,让商店保存所有的顾客购买的信息,等到下一次购买可以知道这个顾客以前购买的内容代价非常大的。所以商店为了避免这个代价,索性就认为每次的购买都是一次独立的新的购买。

 

浅台词:商店不区分对待老顾客和新过客。这就是无状态的。但是,商店为了提高收益。她是想鼓励顾客购买的。所以告诉你,只要你在一个月内购买了5瓶以上的啤酒,就送你一个酒杯。我们看看这种情况我们怎么去实现呢?A,给顾客发放一个磁卡,里面放有顾客过去的购买信息。这样商店就可以知道了。这就是cookie.B,给顾客发放一个唯一号码,号码制定的顾客的消费信息,存储在商店的服务器中。这就是session。最后,商店可以全局的决定,是5瓶为送酒杯还是6瓶。这就是application。其实,这些机制都是在无状态的传统购买过程中加入了一点东西,使整个过程变得有状态这个角度上讲,SessionCookies都可以归为跨页面的状态。但是session跨不出一次会话,Cookies跨不出两端的限制。Application,则是关联这个网络应用程序的。


HTTP 就是一个很好的无状态协议的示例,它建立在客户机-服务器请求和响应的基础之上。在 HTTP 中,不会为下一次请求维护这次请求中客户机-服务器间交互的信息。
当然,由于无法维护状态,因特网将只能成为漂亮的百科全书、电子黄页以及 Shockwave.com 上很酷的动画游戏。因此,出现了一些技巧在 HTTP 上模拟有状态会话。有状态信息可以存储在 HTML 表单域或用户机器的 cookie 中,也可以附到超级链接中。然后,应用程序开发人员负责管理、跟踪和维护客户机的状态。


2、无状态是一个协议问题

      一个服务器究竟是无状态的还是有状态的,这取决于应用协议而不是实现。如果应用协议规定某个报文的含义在某种程度上取决于先前的报文,那么就不可能提供无状态的交互。

      从本质上讲,无状态的问题的焦点在于应用协议是否承担可靠传输的责任。为了避免问题发生,确保交互的可靠性,应用协议的设计者必须确保每个报文绝无二义性。也就是说,报文既不能依赖是否被按序交付,也不能依赖先前已经被交付的报文。从本质上讲,协议设计者必须确保:无论请求什么时候到达以及到达几次,服务器都给出相同的相应。数学家用术语幂等(idempotent)来指一个总是产生相同结果的数学运算。用这个术语来称呼这样一些协议:无论报文到达几次,它们都能确保服务器给出相同的响应。

      如果一个互联网中的下层网络可能使报文重复、延迟,或者传送失序,或者运行客户应用的计算机可能意外崩溃,那么服务器必须是无状态的。如果应用协议被设计成各个操作是幂等的,则服务器只能是无状态的





0 0
原创粉丝点击