汉无为 / 分布式 / 分布式配置管理平台的设计与实现

0 0

   

分布式配置管理平台的设计与实现

2017-02-01  汉无为

 随着业务的发展,应用系统中的配置通常会越来越多,常见的一些应用配置大致会有数据源配置,数据源组件配置,业务组件配置等,对于这类配置都会比较稳定且较少变化,通常会放在文件中随应用一起发布。但实际中会有某些配置信息变化有一定频率和规律,并且希望能够做到尽量实时,比如一些营销类,或活动类应用系统,若使用传统的配置文件,加上重新发布应用可能会有些不方便,因此,才有了分布式配置管理平台,旨在能更好地解决这类问题。本文将介绍相关细节,及一个轻量的开源实现diablo(https://github.com/ihaolin/diablo)


分布式配置平台的一些应用场景


分布式配置,也即配置中心。通常有以下的场景或需求,可以需要考虑使用

分布式配置: 


  • 对某些配置的更新,不想要重启应用,并且能近似实时生效;

  • 希望将配置进行统一管理,而非放入各应用的配置文件中;

  • 对于某些应用系统,其某些配置变更比较频繁,规律;

  • 通常配置中心也可作为在其他分布式应用中的感知组件,比如典型的Zookeeper;

  • ...。


分布式配置平台需要满足的一些基本特性


对于一个可靠的分布式配置平台,大致应该满足一些基本特性,如:


  • 高可用性:服务器集群应该无单点故障,即只要集群中还有存活的节点,就能提供服务;

  • 容错性:容错性主要针对客户端,应保证即便在配置平台不可用时,也不影响客户端的正常运行;

  • 高性能:对于配置平台,主要操作则是获取配置,不能因为获取配置给应用带来不可接受的损失;

  • 可靠的存储:这包括数据的备份容灾,一致性等,通过数据库和一些运维手段可以解决;

  • 近似实时生效:对于配置的变更,客户端应用能够及时感知;

  • 负载均衡:为了尽量提升服务器集群的性能及稳定性,应尽量保证客户端的请求能尽量均衡负载到各服务器节点;

  • 扩展性:服务器集群应该保证做到无感扩容,以提升集群服务能力;

  • ...。


分布式配置平台Diablo的设计与实现


Diablo架构设计


Diablo的架构设计比较简单轻量,如图:



  • Apps:及各类业务应用实例;

  • Servers:为客户端提供获取配置服务的Server集群;

  • Redis Storage Service:用作数据存储。


Diablo模型设计


  • 应用(App):通常,对于一个用于各外部系统的平台,都可以抽象这些系统为应用,用于标识或是分组。对于应用环境,个人觉得应交由应用去处理,而不是在平台为各应用提供不同环境,比如可以通过应用名称就能区分不同环境。除此外,通常需要让应用提供一些安全方面的配置,如签名Key,加密Key等,可用于在与外部应用交互中作一些安全处理(如签名,加密等);

  • 配置项(Config):对于配置平台,其数据模型比较简单,核心数据就是配置项。配置项除了基本的配置名称和配置值外,通常还需要有用于判定配置项是否变更的字段,可以用MD5值等。


对等的服务器集群


Diablo集群中的Server被视为是对等的,即各节点没有主从(Master/Slave)关系,是逻辑相等的,这样就避免了Master/Slave架构带来的问题,如数据同步延迟,数据丢失等问题。


高性能处理


客户端应用获取配置时,仅会从本地缓存中获取,开发人员在控制台更改配置后,会通知客户端刷新缓冲;


使用Redis作存储


配置平台本身并没有太多复杂的关联关系,因此使用NoSQL也能满足常用的查询。在设计存储Key上,因尽量保证Key的简洁清晰,比如,存储应用记录,可以以apps:1来标识一条记录,而存储结构最好使用hash,而不是使用JSON字符串。在使用Redis时,diablo避免使用了一些特殊函数,如管道,事务等,因为这些函数在一些Redis的高可用解决方案(如Redis Cluster,Redis Proxy等)中通常不支持,这样用户可以自由使用不同的Redis高可用方案。


客户端的实现


  • 重试等待:diablo会通过重试等待等机制保证,在服务端集群不可用时,也不会影响客户端应用的正常运行,而是等待集群恢复;

  • 请求负载:为了使服务器集群的各节点的负载尽量均衡,在客户端进行请求处理前,服务端会为客户端分配一个可用的Server节点,后续的请求将在该节点上,这里使用的负载算法是一致性哈希;

  • 额外参数:通常对于客户端实现,在与服务器交互过程中,除了必要的数据外,还会携带一些额外参数,如客户端版本号(为后期作兼容性处理),语言类型(后端可针对不同语言进行处理)等。


配置更新实时生效


配置更新实时生效是配置平台的核心功能之一,对于获取配置的方式,大致有两种模式:


  • Pull模式:即客户端主动向服务端拉取配置信息,通常是客户端定时轮询拉取。这种方式最简单稳定,但是存在时间间隔问题,间隔太长,配置延迟更新越大,间隔太短对服务器会造成过多的压力;

  • Push模式:即当配置发生变更时,服务端主动推送更新至各个客户端。这种方式能保证配置更新实时生效,但需要在客户端/服务端建立长链接,服务端需要处理各种异常情况和协议规范,保证更新能实时推送成功,实现起来相对麻烦些。


diablo使用了特殊Pull模式,即(长轮询)Long Pulling。当客户端发起Http请求后,服务端接收处理完请求,并不会立即返回客户端,而是等待一定条件发生或超时后才返回客户端,这里的一定条件就是当有配置发生变更时,这样就有效减少了客户端请求,也达到了实时生效的目的。对于Java长连接的实现,主要使用了Servlet规范中的AsyncContext,使得服务端接收到请求后,并不会让Servlet容器立即返回客户端,而是当调用AsyncContext.complete()方法时,才会返回。


客户端语言类型


diablo默认实现了Java语言的客户端,希望以后能支持node,go,python等语言。由于diablo仅通过Http接口提供服务,不同语言只要遵循API接口,即可实现不同的语言版本。若读者有意实现,可参考该客户端规范,下图为客户端与服务端的交互过程:



diablo实践建议


服务器集群部署:对于一个高可用的服务器集群,建议可以nginx等代理服务器作转发,这样在服务器集群发生变化时,客户端应用也不用更新任何配置,如:



应用环境区分:对于需要区分不同环境的应用,可以通过不同的应用名称作区分,如app_dev,app_test。但对于生产环境,都建议与其他环境隔离,独立部署。


总结


以上,则是有关分布式配置管理平台设计与实现的相关细节,也欢迎issue和fork项目diablo。 


-END-


架构文摘

ID:ArchDigest

互联网应用架构丨架构技术丨大型网站丨大数据丨机器学习

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多