`
hax
  • 浏览: 952733 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Comet和REST是否有冲突?(兼REST辩论之观感)

    博客分类:
  • AJAX
阅读更多
这两天看了激烈讨论的帖子http://robbin.iteye.com/blog/82227,其中辩论双方都谈到Fielding的名言:HTTP不是Transport protocol(这个其实比较难理解的,主要是俺们英文差,不能区别Transfer和Transport的差别)。

抛开这个已经被锁定而无法继续回帖的帖子不谈,我就想到了Comet,按照我的理解,Comet就是利用HTTP来作Transport……而这样不是不符合REST了?

最后我再此谈一点对前面这个辩论的观感。偶本人对于分布式的理解是很浅薄的。但是我发现在后期的讨论中,其中一方因名责实。 其实Fielding同志作为HTTP的设计者之一,当然最有资格声明HTTP的设计意图。按照我的理解,HTTP只是他们(包括TBL等)对于整个Web架构设想的一环。因此REST论文,阐述的是整个对于web的世界观。因此他解说HTTP不是RPC,是从方法论层面来说的,如果偏要坚持说HTTP就是protocol level的东西,乃至载上tcp/udp包也可以,那就真的只能感叹“有点风马牛不相及”了。
分享到:
评论
24 楼 legend 2007-07-08  
张三打的牌跟张三这个会话是有关的,肯定也是保存在张三这局牌的会话中的,所以它当然是会话状态。如果你说这局牌是一个资源,这个状态是资源本身的状态,而跟张三无关的话,那么请问,如果你不以 Session 形式保存这个你说的资源的状态,那么你打算把这个资源的状态怎么样保存在服务器上?以 Appliction 的级别保存吗?如果以 Application 形式保存,难道不是更影响系统的可伸缩性吗?
23 楼 dlee 2007-07-08  
winterwolf 写道
恩 将状态看作资源 就无状态了。

对,一局牌其实是一个抽象的资源,这个资源的状态,客户端可以获取、操作和修改,但是状态始终是保存在服务器端的。
上面我说的一个工作流,其实也是一个抽象的资源,它的状态也是保存在服务器端的。每个用户执行的一步操作,不能看作是从属于这个用户自身的状态,而是改变了这个工作流资源的状态。

这些场景都与REST并不冲突。

REST的无状态服务器的架构约束,直接继承自客户-无状态-服务器(Client-Stateless-Server,CSS)架构风格。
Fielding 写道
3.4.3 客户-无状态-服务器(Client-Stateless-Server,CSS)

客户-无状态-服务器风格源自客户-服务器风格,并且添加了额外的约束:在服务器组件之上不允许有会话状态(session state)。从客户端发到服务器的每个请求必须包含理解请求所必需的全部信息,不能利用任何保存在服务器上的上下文(context),会话状态全部保存在客户端。

这些约束改善了可见性、可靠性和可伸缩性3个架构属性。可见性的改善是因为监视系统再也不必为了确定请求的全部性质而查看多个请求的数据。可靠性的改善是因为这些约束简化了从部分故障中恢复的任务[133]。可伸缩性的改善是因为不必保存多个请求之间的状态,允许服务器组件迅速释放资源并进一步简化其实现。

客户-无状态-服务器风格的缺点是:因为我们不能将状态数据保存在服务器上的共享上下文中,通过增加在一系列请求中发送的重复数据(每次交互的开销),可能会降低网络性能。

注意看,这里明确说的是会话状态,而不是其他类型的状态。
Fielding 写道
5.1.3 无状态

我们接下来再为客户-服务器交互添加一个约束:通信必须在本质上是无状态的,如3.4.3小节中的客户-无状态-服务器(CSS)风格那样,因此从客户到服务器的每个请求都必须包含理解该请求所必需的所有信息,不能利用任何存储在服务器上的上下文,会话状态因此要全部保存在客户端。

这个约束导致了可见性、可靠性和可伸缩性三个架构属性。改善了可见性是因为监视系统不必为了确定一个请求的全部性质而去查看该请求之外的多个请求。改善了可靠性是因为它减轻了从局部故障[133]中恢复的任务量。改善了可伸缩性是因为不必在多个请求之间保存状态,从而允许服务器组件迅速释放资源,并进一步简化其实现,因为服务器不必跨多个请求管理资源的使用。

与大多数架构上抉择一样,无状态这一约束反映出设计上的权衡。其缺点是:由于不能将状态数据保存在服务器上的共享上下文中,因此增加了在一系列请求中发送的重复数据(每次交互的开销),可能会降低网络性能。此外,将应用状态放在客户端还降低了服务器对于一致的应用行为的控制,因为这样一来,应用就得依赖于跨多个客户端版本(译者注:例如多个浏览器窗口)的语义的正确实现。

一个忠告:在声称自己完全理解了Fielding的含义,甚至比Fielding更懂HTTP之前,最好还是慎重一些。
22 楼 winterwolf 2007-07-07  
恩 将状态看作资源 就无状态了。

资源千秋万载一统。。
21 楼 netfishx 2007-07-07  
dlee前面关于“状态”的解释说到我心里去了。早就想说了,貌似有些人对状态的理解无限扩大化了
20 楼 winterwolf 2007-07-07  
dlee 写道
winterwolf 写道
dlee说过俺英文不及格滴 lordaeron也不及格吗

你这个同志就是喜欢对号入座,我没有说你啊。
Lordaeron的英语显然不及格,连上面我贴的那么浅显的英文都能读错,凭空诬陷好人(WebDAV)的清白,如果再继续大言不惭实在是有些过分了。


哦那就好 不能冤枉好人嘛

如果用webdav协议构建rest系统是不是比http更优秀那 ? 比如灵活性 效率等等 而且不仅可以通过浏览器访问还可以通过windows和linux网络文件夹访问或编辑rss atom wiki. 后边还可以和svn集成起来


19 楼 dlee 2007-07-07  
winterwolf 写道
dlee说过俺英文不及格滴 lordaeron也不及格吗

你这个同志就是喜欢对号入座,我没有说你啊。
Lordaeron的英语显然不及格,连上面我贴的那么浅显的英文都能读错,凭空诬陷好人(WebDAV)的清白,如果再继续大言不惭实在是有些过分了。
18 楼 dlee 2007-07-07  
to hax:
Comet确实并不是REST主要考虑要支持的场景。REST主要支持的场景是什么?在论文的4.1小节“万维网应用领域的需求”中讲的比较清楚。
我同意你的意见,Comet确实超出了Fielding当初所设想的典型场景,也就是Comet与REST不相容的说法。就目前来说,Comet的需求还不是很普遍。这个观点我与你不同,可能是因为我们所做的开发类型差别很大。我们可以保持不同的观点,共同观察技术未来的发展方向。
HTTP设计的原意就是所有的请求都是由客户端发起,服务器响应,而且请求是短期的。为何要这样设计?因为这样设计服务器端的可伸缩性最好。这个问题早已得到了证明,我们无需再争论HTTP这样设计是否合理。Comet确实超越了HTTP设计的原意,这导致了它存在明显的服务器端可伸缩性问题,再次证明了REST的正确性和预见性(识别出架构不匹配的能力)。服务器端目前有各种work around,你可以看一下Jetty的方案,我贴过一篇文档,想必你已经仔细读过。

我不是很了解使用XHR如何来实现Comet,刚好可以在这里请教一下,麻烦你再进行一些解释。我目前看到过的解决方案,包括Pushlets、Buyeux,使用的都是script标签。这种方式的实现看来要比XHR的实现更简单。

我从来没有说过REST包治百病的话,只是很讨厌某些人故意曲解Fielding的原意,再去误导群众。当然不是所有的应用都应该将状态完全保存在客户端,例如,工作流类型的应用,需要跨越多个客户端、由多个人、在一段时间内完成,这些状态就应该保存在服务器端。

还有一个重大的误解我要在这里指出:我觉得Fielding所说的状态,指的应该是与某一个单独客户端相关的状态,明确地说,就是我们以前习惯于保存在session中的状态。你说的4人麻将的状态其实并不是Fielding所说的那种状态。你先告诉我,如果按照传统的方式来实现,4人麻将的状态在服务器端是要保存到每个客户端的session中吗?如果那样的话,这个状态是不是会有4个副本?我们不能把“状态”无限扩大,认为保存在服务器端的所有状态都是Fielding所说的那种状态。

出于安全考虑,当然可以将Fielding所说的那种特定的状态保存在服务器端。REST并不是禁止你做这个禁止你做那个,REST并不是孙悟空头上的紧箍咒,很多人这样理解REST是完全错误的。REST只是告诉你,如果尽可能遵循REST的架构约束,你可以获得很多利益。如果违反REST的架构约束,你就会付出一些代价。例如将状态保存在服务器端会损害服务器端的可伸缩性。这样做是否值得,需要由设计者本人来做权衡。如果服务器的并发访问量不是很大,那么这样做的代价完全可以承受。但是如果服务器的并发访问量非常巨大,这样做可能会造成严重的后果。其实我以前基于Web MVC框架做开发的时候,也是尽量不在session中保存东西的。session中保存的东西越多,做集群就越困难,服务器端的可伸缩性就越差。这些常识性的问题,一再在这里争论,是不是会显得很无聊?
17 楼 hax 2007-07-07  
是啊,我也觉得,代理既要和服务器连,又要和client连,不撑死才怪哈。。。被断开也没用,因为comet会自动重连。所以,我杞人忧天一下:comet要是流行起来,是不是代理都要完蛋啊。。。
16 楼 andot 2007-07-07  
hax 写道

顺便问一句,comet对于proxy会有什么影响捏?

正常的 proxy 都会有个数据写入(请求)和数据读出(响应)时间的限制,对于 comet 这种响应时间无限的连接,到超时就会自动强行断掉,如果系统设计时没有考虑到这一点,可能会影响系统的正常运行。另外,代理与实际的Web服务器之间保持连接是有代价的,那就是它所使用的端口数,所以,代理服务器一般是承受不了这种保持大量连接的应用的。
hax 写道

不可否认,这样使用HTTP确实有实际的需求。除了穿透防火墙之外,享受BS的零部署也是非常大的原因。

非常同意!实际上,许多 C/S 模式系统被转到 B/S 模式上来,主要看中的就是零部署这一点。
15 楼 winterwolf 2007-07-07  
hax 写道

dlee的回复不是针对你的。莫非lordaeron是你的马甲


dlee说过俺英文不及格滴 lordaeron也不及格吗
14 楼 andot 2007-07-07  
REST 不是所有的基于 HTTP 的应用都可以使用的一种构架风格。

REST 这种构架风格可以被典型的应用于新闻咨询类网站、论坛、相册、Blog、在线视频等系统中,因为这类系统所存取得主要内容就是资源,这类资源可以被缓存,可以被重新组合,可以很方便直观的用 URL 来表示,可以很直观的用 HTTP 中的方法原语来描述对它的操作。

REST 这种构架风格不适用于在线游戏(如 hax 大大所说的麻将,其它的五子棋、围棋、扑克、或者砍人游戏也属此类),在线即时通讯,其它一些从 C/S 模式转为 B/S 模式的系统等。这类系统典型的特点是信息不能够或者说不应该被缓存,可以被重新组合的是接口而不是资源,交互的信息不是纯粹的资源,很难作为一个资源来用 URL 描述,施加在这些信息的操作无法用 HTTP 中的方法原语来很好的描述。

另外,还有一些复杂的系统,例如网上商城,它其中一部分内容属于资源,而另一部分不属于资源,因此这类系统可以被部分的设计为 REST 构架风格的,而不需要完全的 REST 风格。

我们没有必要为了 REST 而 REST,就像我们不应该为了 Ajax 而 Ajax 一样。我们应当首先看清它适合做什么,不适合做什么,然后再讨论在一个项目中是否采用它,或者那一部分采用它。否则技术就不再是帮你完成任务的工具,而会成为你完成任务的负累。

所以,Comet 有必要 REST 吗?
13 楼 hax 2007-07-07  
winterwolf 写道
dlee 写道

Fielding在论文中根本就没有这样抨击过WebDAV,而是从正面表扬WebDAV是一个行为良好的扩展。这说明你根本没有看懂Fielding的原文,你的英文程度很差。WebDAV开发恰好我前些年也做过,WebDAV是把HTTP4种动词都用上了。WebDAV是面向服务器端的文件系统的,它是将资源映射到服务器端的文件系统。你并不懂WebDAV,为何还要在这里卖弄呢?

你的目的莫非就是为了证明:其实Fielding并不懂RPC,我Lordaeron要比Fielding更懂RPC,甚至比Fielding更懂HTTP?
其实谁比谁更懂HTTP我并不是很关心,我们翻译这篇论文也是想为了给大家提供一个方便,让大家不至于被某个歪嘴和尚误导。但是你这样明目张胆歪曲Fielding的观点,我却感觉有点愤慨了。


我不精通webdav但我在用webdav而且发现它很强大(webdav不只支持4个动作) 。 我对webdav很有兴趣

卖弄这个词是什么意思 ? 因为你比别人了解 所以其他人就不能谈论某某技术 只要谈到了就是卖弄 ?

我觉的你的态度真是有问题 。

置于说fd如何如何 我是回复hax的发言 在看了原文后也改掉了 没必要发这么大火吧  ?


dlee的回复不是针对你的。莫非lordaeron是你的马甲
12 楼 hax 2007-07-07  
我觉得对照dlee所摘录的这段话,comet真的非常接近于REST的反面。
1. 使用comet的目的一个是变相获得服务器端push的能力。而HTTP本身并非为此设计,所有的method都是客户端主动发起的,如何能表达服务器端主动的动作呢?服务器端push,并不能映射到任何可以用HTTP语义表达的事物,用户代理和中间组件也不能真正理解它。(顺便问一句,comet对于proxy会有什么影响捏?)他们看到的只是一个始终没有结束的GET响应。要理解它,需要对响应的方式进行理解。
2. 基于comet可以实现通讯协议,例如dlee告诉我们的bayeux。http在其中扮演的角色,只是transport而已,我没有在其中看到任何REST风格。
引用
Bayeux is a protocol for transporting asynchronous messages over HTTP. The messages are routed via named channels and can be delivered: server to client, client to server and client to client (via the server).

3. 不可否认,这样使用HTTP确实有实际的需求。除了穿透防火墙之外,享受BS的零部署也是非常大的原因。
11 楼 winterwolf 2007-07-07  
dlee 写道

Fielding在论文中根本就没有这样抨击过WebDAV,而是从正面表扬WebDAV是一个行为良好的扩展。这说明你根本没有看懂Fielding的原文,你的英文程度很差。WebDAV开发恰好我前些年也做过,WebDAV是把HTTP4种动词都用上了。WebDAV是面向服务器端的文件系统的,它是将资源映射到服务器端的文件系统。你并不懂WebDAV,为何还要在这里卖弄呢?

你的目的莫非就是为了证明:其实Fielding并不懂RPC,我Lordaeron要比Fielding更懂RPC,甚至比Fielding更懂HTTP?
其实谁比谁更懂HTTP我并不是很关心,我们翻译这篇论文也是想为了给大家提供一个方便,让大家不至于被某个歪嘴和尚误导。但是你这样明目张胆歪曲Fielding的观点,我却感觉有点愤慨了。


我不精通webdav但我在用webdav而且发现它很强大(webdav不只支持4个动作) 。 我对webdav很有兴趣

卖弄这个词是什么意思 ? 因为你比别人了解 所以其他人就不能谈论某某技术 只要谈到了就是卖弄 ?

我觉的你的态度真是有问题 。

置于说fd如何如何 我是回复hax的发言 在看了原文后也改掉了 没必要发这么大火吧  ?
10 楼 dlee 2007-07-07  
原文 写道
That is why HTTP goes through firewalls. Most of the recently proposed extensions to HTTP, aside from WebDAV [60], have merely used HTTP as a way to move other application protocols through a firewall, which is a fundamentally misguided idea. Not only does it defeat the purpose of having a firewall, but it won’t work for the long term because firewall vendors will simply have to perform additional protocol filtering. It therefore makes no sense to do those extensions on top of HTTP, since the only thing HTTP accomplishes in that situation is to add overhead from a legacy syntax. A true application of HTTP maps the protocol user’s actions to something that can be expressed using HTTP semantics, thus creating a network-based API to services which can be understood by agents and intermediaries without any knowledge of the application.

译文 写道
这就是为何HTTP可以穿越防火墙的原因。大多数当前提议的对于HTTP的扩展,除了WebDAV[60]以外,仅仅使用HTTP作为一种使其他的应用协议穿越防火墙的方法,这从根本上来说是一种有误导性的想法。不仅仅是因为这种扩展方式挫败了拥有一个防火墙的目的,而且从长远来看它将无法工作,因为防火墙的厂商将会不得不执行额外的协议过滤。因此这种扩展方式对于那些在HTTP之上的扩展而言是没有意义的,因为在这种情况下HTTP所完成的唯一的事情就是添加了来自一个遗留语法的负载(译者注:即添加了额外的HTTP协议负载)。一个真正的HTTP应用应该将协议用户的动作映射到能够使用HTTP语义来表达的某个事物,以这种方式创建一个基于网络的API来提供服务,能够被用户代理和中间组件所理解,而不需要知道关于应用的任何知识。
9 楼 winterwolf 2007-07-07  
关于webdav rest原文中只提到上面一句子 没有批判webdav的意思啊?

http本身也应该修改 如果它不适合需求就应该被替换 而不应该让所有的人为了http而改变自己的需要 将自己都放进笼子里

webdav是一个很灵活的协议, 基于webdav也可以restful 而且相对http更灵活
8 楼 dlee 2007-07-07  
to hax:
这是一个很好的讨论话题。我的观点是这样的:
1. 首先,Comet类应用相对来说并不是一种非常普遍的场景,而是较为特殊的一种场景。REST是为Web应用常见的场景而优化过的,这些常见的场景并不包括Comet。
2. GET方法的请求默认情况下是要缓存的,但是不是说REST要求GET方法就必须要缓存。Comet这种情况是不需要缓存的。
3. GET方法的要求是它不应该改变服务器的状态。Comet也不会改变服务器的状态,它改变的是客户端的状态。
4. Comet从实现方式上来说,一般都是将服务器事件封装在一段script标签(就是一段可执行的JavaScript代码)中,客户端接收到之后立即执行。即使里面携带有数据,它还是一段可执行的代码,所以可以把它列为按需代码的一种。按需代码风格的问题是:
Fielding 写道
像远程求值风格一样,最大的限制是由于服务器发送代码而不是简单的数据,因此缺乏可见性。如果客户端无法信任服务器,缺乏可见性会导致明显的部署问题。

这个问题同样适用于Comet。与普通按需代码应用不同的是,Comet的一个请求永远不会结束。

至于你说的搓麻将的应用,它的计算一定要在服务器端完成,状态就一定要保存在服务器端吗?我觉得你的理解有些问题。很多年以前使用EJB的时候,尽管有Stateful Session Bean,但是绝大多数场合我们只使用Stateless Session Bean,其原因是类似的。
7 楼 hax 2007-07-07  
倒,被误导大了。。。我倒是扫了Fielding原文一下,就看到提到webdav了,咋没看出来意义完全相反捏。。。看来我要好好进修英文。。。

我现在粗略的看完了译文的前4章。。。

关于comet,你说是COD的一种,俺不能同意。按照我的理解,comet并非是下载代码对客户端进行扩展,而是可以push任何东西到客户端。因此它可以push代码,也可以push数据,或者消息,或者指令,或者事件。重要的问题是两点,第一是comet显然不太可能被缓存;第二是它可以用于持续的传递小粒度的数据。因此我觉得它似乎是transport,而不一定是transfer。因此我觉得comet是不符合REST的。

事实上,我感到一些web应用的需求也与REST之“分布式超媒体”的需求不同。例如一个web游戏,比如搓麻将,它是即时应用,它的计算部分很可能只能在server端完成,因此它既不是无状态,又不能缓存。当然,也许应该用其他方式(如Flash,applet)来编写游戏。。。但是我们确实应该可以用AJAX和comet来编写这样的web应用。
6 楼 xin_wang 2007-07-06  
winterwolf 写道
hax 写道
fielding同志没有评价过comet。。。那时候还没有comet这个名词(寒一个),他只是说http不是rpc,另外批评了一下webdav。


webdav我感觉很好 fielding这家伙是个老顽固 抓住http当令箭


6.5.3 HTTP is not a Transport Protocol
Most of the recently proposed extensions to HTTP, aside from WebDAV [60], have merely used HTTP as a way to move other application protocols through a firewall, which is a fundamentally misguided idea.

除WebDAV之外,近几年大多数对于HTTP的扩展建议,都仅仅把HTTP作为一种“搬运其他应用协议穿越防火墙”的手段,而这种概念从根本上是一种被误导的想法。
5 楼 dlee 2007-07-06  
to hax:
你看一下论文的5.1.7小节,Comet可以看作是按需代码的一种形式,它是REST的一种可选的约束。

相关推荐

Global site tag (gtag.js) - Google Analytics