Apollo客户端设计及实时获取服务端配置原理

参考:https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97#%E5%9B%9B%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%AE%BE%E8%AE%A1

 

 

上图简要描述了Apollo客户端的实现原理:

  1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)
  2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。
    • 这是一个fallback机制,为了防止推送机制失效导致配置不更新
    • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
    • 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟。
  3. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
  4. 客户端会把从服务端获取到的配置在本地文件系统缓存一份
    • 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
  5. 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知

 

Long Polling长轮询详解,参考地址:https://www.jianshu.com/p/d3f66b1eb748

介绍

众所周知,数据交互有两种模式:Push(推模式)、Pull(拉模式)。

推模式指的是客户端与服务端建立好网络长连接,服务方有相关数据,直接通过长连接通道推送到客户端。其优点是及时,一旦有数据变更,客户端立马能感知到;另外对客户端来说逻辑简单,不需要关心有无数据这些逻辑处理。缺点是不知道客户端的数据消费能力,可能导致数据积压在客户端,来不及处理。

拉模式指的是客户端主动向服务端发出请求,拉取相关数据。其优点是此过程由客户端发起请求,故不存在推模式中数据积压的问题。缺点是可能不够及时,对客户端来说需要考虑数据拉取相关逻辑,何时去拉,拉的频率怎么控制等等。

详解

说到Long Polling(长轮询),必然少不了提起Polling(轮询),这都是拉模式的两种方式。

Polling是指不管服务端数据有无更新,客户端每隔定长时间请求拉取一次数据,可能有更新数据返回,也可能什么都没有。

Long Polling原理也很简单,相比Polling,客户端发起Long Polling,此时如果服务端没有相关数据,会hold住请求,直到服务端有相关数据,或者等待一定时间超时才会返回。返回后,客户端又会立即再次发起下一次Long Polling。这种方式也是对拉模式的一个优化,解决了拉模式数据通知不及时,以及减少了大量的无效轮询次数。(所谓的hold住请求指的服务端暂时不回复结果,保存相关请求,不关闭请求连接,等相关数据准备好,写会客户端。)

前面提到Long Polling如果当时服务端没有需要的相关数据,此时请求会hold住,直到服务端把相关数据准备好,或者等待一定时间直到此次请求超时,这里大家是否有疑问,为什么不是一直等待到服务端数据准备好再返回,这样也不需要再次发起下一次的Long Polling,节省资源?
主要原因是网络传输层主要走的是tcp协议,tcp协议是可靠面向连接的协议,通过三次握手建立连接。但是所建立的连接是虚拟的,可能存在某段时间网络不通,或者服务端程序非正常关闭,亦或服务端机器非正常关机,面对这些情况客户端根本不知道服务端此时已经不能互通,还在傻傻的等服务端发数据过来,而这一等一般都是很长时间。当然tcp协议栈在实现上有保活计时器来保证的,但是等到保活计时器发现连接已经断开需要很长时间,如果没有专门配置过相关的tcp参数,一般需要2个小时,而且这些参数是机器操作系统层面,所以,以此方式来保活不太靠谱,故Long Polling的实现上一般是需要设置超时时间的。

实现

Long Polling的实现很简单,可分为四个过程:

  • 发起Polling
    发起Polling很简单,只需向服务器发起请求,此时服务端还未应答,所以客户端与服务端之间一直处于连接状态。

  • 数据推送
    如果服务器端有相关数据,此时服务端会将数据通过此前建立的通道发回客户端。

  • Polling终止
    Polling终止情况有三种:
    若服务端返回相关数据,此时客户端收到数据后,关闭请求连接,结束此次Polling过程。
    若客户端等待设定的超时时间后,服务端依然没有返回数据,此时客户端需要主动终止此次Polling请求。
    若客户端收到网络故障或异常,此时客户端自然也是需要主动终止此次Polling请求。

  • 重新Polling
    终止上次Polling后,客户端需要立即再次发起Polling请求。这样才能保证拉取数据的及时性。


作者:涤生YQ
链接:https://www.jianshu.com/p/d3f66b1eb748
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2020-01-17 16:29  xyfaneast  阅读(1573)  评论(0编辑  收藏  举报