对于数据转发我们一般就两种模式,一种时推模式,一种时拉模式。下面我们简单介绍一下推模式和拉模式。
推模式
该模式下,一般是消息源直接推送给目标群体或推送给Broker,由Broker推送给目标群体。
这个模式下,每一个接收者都有一份数据复制。这种情况下,写入压力非常大,但是读取的压力非常小并且实时性非常高。是一种以空间换时间的模式。
拉模式
该模式下,一般是消息源将数据推送到存储中,目标群体定时或因为某些原因触发拉取动作。
这个模式下,所有接收者共享一份数据复制。这种情况下,写入压力小,但是读取压力偏大,并且实时性偏弱。是一种以时间换空间的模式。
两种模式在系统设计上的影响
推模式,实现上看起来比较简单,但考虑到订阅群体的变化等情况,其实并不是很简答的,并且在存储的消耗上也是很巨大的。
拉模式,实现上触发的随机性很大,并且需要考虑到同步的数据的数量是否会给网络和存储带来巨大的压力。
Comet和两种模式的关系
Comet本质上,是一个http请求服务器而服务器当前没数据,等服务器有数据或超过一定时间才返回给客户端。从这个层面上Comet是一个拉模式和推模式的混合体,为什么这么说?
因为有下面几个原因:
Comet请求连上服务器的瞬间,它所关注的数据已经发生了很多变化,服务器可以立刻返回给客户端。那么这相当于是一个拉模式,客户端和服务器进行了基于检查点的同步。
Comet请求连上服务器时,它所关注的数据还没有发生变化,在该链接没有超时的阶段内,数据发生了变化,服务器将数据返回给客户端。这样就相当等于通过拉取动作去完成了一个推模式。
Comet在IM上的应用
我在前面的博客中介绍了我的IM群组设计。我们可以通过Comet来实现它。下面我就简单讲下如何实现该功能。
客户端使用POST方法发起一个http请求,其中请求的形式{channel1:sync_key1},{channel2:sync_key2}。
当服务器接收到这个请求的时候,按要求遍历所有的channel,如果存在数据变化就以{channel1:{sync_key:sync_key1,data:[.....]},{channel2:{sync_key:sync_key2,data:[....]}}这种数据形式返回。
如果服务器上任何channel都没有变化,就将自己加入所有channel的订阅中。当接收到任何变化的时候,我们就再次遍历所有channel,并按照前面的数据返回数据。
当客户端收到数据返回的时候,将数据展示,同时用新的sync_key发起http请求,关注数据变化。