配置信息就是程序加载时候需要设置的信息,一般我们可以通过在代码中设置,在配置文件中设置,在配置中心配置来设置我们需要的信息。

配置方式

配置方式一般有两种:

  • 本地配置,包括代码中耦合,配置文件加载。
  • 适用于分布式系统的集中式资源配置。

本地配置

代码耦合

将配置直接写在代码中很方便,但是对于后期的维护修改十分的不友好,需要重新发布才能修改完成,基本上是不用的。

配置文件

将配置信息写在配置文件中是最常见的方式,程序自动加载配置文件的信息,然后进行处理,有需要只要修改对应的配置信息就可以,实现了对业务代码的解耦。

但是随着系统的发展,分布式系统的出现,我们很多实例都是通过集群的方式进行部署,这个时候在集群的每个节点上都会有一份配置文件,随着规模的扩大,修改每个节点上的配置文件又变的容易出错难以维护,因此我们需要一种集中式的配置方式。

集中式资源配置

在分布式的情况下,我们需要一个共享配置的中心,使用集中式的资源管理配置平台的好处

  • 配置信息统一管理
  • 动态获取更新配置文件
  • 降低运维成本
  • 降低配置出错率

分布式配置管理服务的本质是一个发布订阅模式的实现。

集中式的配置中心一般都是作为服务发现和动态注册的基础,也是我们常用的几个框架,比如zookeeper,consul,etcd等。我们一般的配置平台都是基于这些组件来实现的,目前这一块做的比较好的就是淘宝的diamonds和百度的disconf,还有一些比如携程的apollo等。

zookeeper

常规使用一些服务发现动态注册组件做配置中心都是一个思路,我们以zookeeper为例,看下他是如何实现分布式配置管理的

整体可以分为3部分

  • zookeeper集群 提供了稳定的配置管理服务,对外提供了接口,外部可以添加、修改配置信息,可以监听配置的变化

  • 配置管理中心 需要自己开发,负责维护配置信息

  • 各个分布式应用 每个应用只需要调用一下ZK的接口,把自己注册到ZK,就可以自动接收配置的变化信息

工作流程原理也很简答

diamond

diamond是淘宝内部使用的一个管理持久配置的系统,它的特点是简单、可靠、易用,目前淘宝内部绝大多数系统的配置,由diamond来进行统一管理。

  • 作为一个配置中心,diamond的功能分为发布和订阅两部分。因为diamond存放的是持久数据,这些数据的变化频率不会很高,甚至很低,所以发布采用手工的形式,通过diamond后台管理界面发布;订阅是diamond的核心功能,订阅通过diamond-client的API进行。
  • diamond服务端采用mysql加本地文件的形式存放配置数据。发布数据时,数据先写到mysql,再写到本地文件;订阅数据时,直接获取本地文件,不查询数据库,这样可以最大程度减少对数据库的压力。
  • diamond服务端是一个集群,集群中的每台机器连接同一个mysql,集群之间的数据同步通过两种方式进行,一是每台server定时去mysqldump数据到本地文件,二是某一台server接收发布数据请求,在更新完mysql和本机的本地文件后,发送一个HTTP请求(通知)到集群中的其他几台server,其他server收到通知,去mysql中将刚刚更新的数据dump到本地文件。
  • 每一台server前端都有一个nginx,用来做流量控制。
  • 图中没有将地址服务器画出,地址服务器是一台有域名的机器,上面运行有一个HTTPserver,其中有一个静态文件,存放着diamond服务器的地址列表。客户端启动时,根据自身的域名绑定,连接到地址服务器,取回diamond服务器的地址列表,从中随机选择一台diamond服务器进行连接。
  • 可以看到,整个diamond的架构非常简单,使用的都是最常用的一些技术以及产品,它之所以表现得非常稳定,跟其架构简单是分不开的,当然,稳定的另一个主要原因是它具备一套比较完善的容灾机制,容灾机制将在下一篇文章中讲述。

disconf

disconf是一套完整的基于zookeeper的分布式配置统一解决方案。

每个模块的简单介绍如下:

  • Disconf-core
    • 分布式通知模块:支持配置更新的实时化通知
    • 路径管理模块:统一管理内部配置路径URL
  • Disconf-client
    • 配置仓库容器模块:统一管理用户实例中本地配置文件和配置项的内存数据存储
    • 配置reload模块:监控本地配置文件的变动,并自动reload到指定bean
    • 扫描模块:支持扫描所有disconf注解的类和域
    • 下载模块:restful风格的下载配置文件和配置项
    • watch模块:监控远程配置文件和配置项的变化
    • 主备分配模块:主备竞争结束后,统一管理主备分配与主备监控控制
    • 主备竞争模块:支持分布式环境下的主备竞争
  • Disconf-web
    • 配置存储模块:管理所有配置的存储和读取
    • 配置管理模块:支持配置的上传、下载、更新
    • 通知模块:当配置更新后,实时通知使用这些配置的所有实例
    • 配置自检监控模块:自动定时校验实例本地配置与中心配置是否一致
    • 权限控制:web的简单权限控制
  • Disconf-tools
    • context共享模块:提供多实例间context的共享。

原理

  • 启动事件A:以下按顺序发生。
    • A3:扫描静态注解类数据,并注入到配置仓库里。
    • A4+A2:根据仓库里的配置文件、配置项,去 disconf-web 平台里下载配置数据。这里会有主备竞争
    • A5:将下载得到的配置数据值注入到仓库里。
    • A6:根据仓库里的配置文件、配置项,去ZK上监控结点。
    • A7+A2:根据XML配置定义,到 disconf-web 平台里下载配置文件,放在仓库里,并监控ZK结点。这里会有主备竞争。
    • A8:A1-A6均是处理静态类数据。A7是处理动态类数据,包括:实例化配置的回调函数类;将配置的值注入到配置实体里。
  • 更新配置事件B:以下按顺序发生。
    • B1:管理员在 Disconf-web 平台上更新配置。
    • B2:Disconf-web 平台发送配置更新消息给ZK指定的结点。
    • B3:ZK通知 Disconf-cient 模块。
    • B4:与A4一样。
    • B5:与A5一样。
    • B6:基本与A4一样,唯一的区别是,这里还会将配置的新值注入到配置实体里。
  • 主备机切换事件C:以下按顺序发生。
    • C1:发生主机挂机事件。
    • C2:ZK通知所有被影响到的备机。
    • C4:与A2一样。
    • C5:与A4一样。
    • C6:与A5一样。
    • C7:与A6一样。