消息系统中pull与push模型比较

在上一个消息路由设计中,大概也有提到过关于pull和push的问题,但没有细说,我们在设计模式中,也就是观察者模式(也叫订阅发布模型)中,也遇到过相同的问题,那么push与pull到底有什么差别?

首先我们来确定一下定义:push(推),主动推送,换言之也就是从服务器发出请求给客户端,客户端接收数据,pull(拉),被动拉取,换言之,客户端去请求服务端,获取服务端的数据。

平时其实也很常见,如果我们网站的数据需要实时动态更新,此时我们有两种解决方案,一种Ajax轮询,从客户端的角度来说,我们可以看做把消息定时的拉下来,而另一种是WebSocket,当服务端生产出消息后,推送到客户端,实时性很强。

在上一次中间件的设计中,我使用的也是push的模型,他的特点是对于客户端而言比较轻松愉快,服务器也似乎不会造成太大压力,但是很显然,客户端无法选择好的接收时刻不一定是一个很好的方法,容易发生丢失消息的情况,于此同时,在同一时刻服务端的压力可能会很大。

这么看来,pull似乎有着若干无法比拟的优点,但其实也有问题,pull的轮询间隔需要很好地指定,如果对于实时性较强的场景,毫无疑问轮询会造成服务器的过大压力,因为其实时性取决于轮询时间间隔。

对于push模型而言,所有的发送状态都存储在服务端,由客户端发送ack之后服务器端可以得知并且重新推送。而对于pull模型而言,获取状态是由客户端来决定的,从存储空间的角度,他们俩也有不同。

pull的轮询次数的取舍,在美团那篇文章中也有提及,一般采用乘二法(如果没记错的话有点像TCP的拥塞控制)。

具体而言,可以看这张对比表:

pull-push

当然,更好的方法其实是push和pull相结合,比如说服务器先push通知客户端更新,客户端收到消息后获取更新。(设计模式中的被动获取也就是这样的):

观察者模式.png

两种模型各有利弊,适合的,才是最合适的。

来源&参考:

消息系统Push/Pull模式分析

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识

已有 2 条评论

  1. 我司使用的Hermes是基于pull的模式,
    感觉这种还是基于场景才有意义。

  2. Aska

    Zookeeper 应该是在服务端工作而不是客户端工作吧?或者是我有点误解表格。

添加新评论