Middleware

配置中心设计

概述

配置中心负责在分布式系统中存储和管理配置相关的数据,它需要完成以下两个基本的职责
1. 根据配置的key读取配置值
2. 在配置值发生变化时,推送变更事件通知

数据模型

配置的key与数据的组织形式主要有两种数据模型
1. 扁平结构:通过groupId和dataId定位配置值,如淘宝的开源的Diamond
2. 树形结构:按树形路径组织配置的key、通过节点存储配置值,如ZooKeeper

在实际的工作经验中,笔者认为树形结构是更为合理的一种组织形式。因为它很容将配置项组织成各种层级的分组,在配置项的查找和隔离上都会更为清晰一些。

实现方式

如果使用树形结构,ZooKeeper本身就是一个很成熟配置服务。但访问ZooKeeper的API并不是十分简洁,也需要很多额外的机制来保证配置中心正常运行,因此通常会基于ZooKeeper再次进行封装和功能完善。

通知机制

如果使用ZooKeeper作为配置数据的存储,ZooKeeper的Watcher本身就是一种很好的事件通知机制。客户端与服务端建立一个长连接,当有数据发生变更时通过私有协议消息通信告知客户端数据变化的情况。

除此之外,客户端也可以采用轮询的方式向服务端发起配置变更的校验。例如在Diamond中,客户端会每隔15秒发起一次,通信方式是HTTP协议。服务端会发布成HTTP Server,客户端每次将配置的key与配置数据的MD5值提交给服务端,服务端比较自身配置key对应配置数据的MD5值,如果发现不一致,则认为客户端的版本滞后,为客户端返回一个拉取数据的通知,客户端重新读取一次配置数据。因为轮询是不断进行的,即使某一次校验出现异常,后续仍可以再次将数据恢复到一致的状态。这样的方式可以使客户端的数据一致性更加可靠。

在这种模式下,Diamond还有很多优化值得借鉴。由于轮询校验是一个非常频繁的操作,Diamond直接将配置的key与配置数据的MD5值放入内存中,可以极大提高性能。无论配置数据体有多大,其MD5值总是固定的32个字符,这也使得载入内存成可能。此外对于配置数据体,Diamond将它们以文件的形式保存在Web Server的磁盘上,当请求一个配置数据时,相当于请求一个Server上的静态文件而无需加载动态的内容。因此Diamond在部署极少Server的情况下,就可以承载大量Client的轮询请求。

本地镜像

配置数据通常是比较重要的数据,一旦无法获取将导致应用无法启动或服务运行。一种常见的使配置数据实现高可用的方式是,在配置中心客户端本地磁盘保存一份配置数据的镜像。这份镜像随配置数据的变更通知而更新,在客户端无法与服务端建立连接时,可以继续通过本地数据读取之前的配置内容。

反馈机制

配置数据是被分布在多台服务器上的客户端共享的,当配置发生变更时需要通知所有客户端更新配置数据。由于通知是一种远程通信,并不能保证一定可以成功,因此需要客户端将当前配置数据的版本反馈给服务器端。变更配置会提升数据的版本,如果客户端没有及时将最近版本反馈回来,则可以判定通知失败、执行再次通知等补救措施。

小结

以上为开发一个配置中心的设计要点,笔者基于这些思想开发的一个开源产品保存在:https://github.com/gaofeihang/beam-cs,欢迎有兴趣的朋友一起进行优化改进。

© 2015, 高飞航.cn. 版权所有.

About gaofeihang

开发工程师,本站的作者。欢迎留下您宝贵的意见!

发表评论

电子邮件地址不会被公开。 必填项已用*标注