作者:个推应用平台基础架构高级研发工程师 阿飞

在微服务架构体系中,由于微服务众多,服务之间又有互相调用关系,因此,一个通用的分布式配置管理是必不可少的。一般来说,配置管理需要解决配置集中管理、在系统运行期间可实现动态配置、配置修改后支持自动刷新等问题。

在大多数微服务体系中,都会有一个名为配置文件的功能模块来提供统一的分布式配置管理。构建配置中心,统一对应用中各个微服务进行管理,对微服务体系的意义重大。

Consul为什么适合做配置管理

Consul作为轻量级的分布式K/V存储系统,搭建方便,可用性高,并且支持多数据中心,提供Web UI进行K/V管理。此外Consul还可以结合Consul-Template或者在代码中引入Consul Client的相关依赖创建Watcher来实时Watch K/V的变化,是配置管理的不二之选。

下图为个推微服务体系基于Consul配置管理的整体设计。其中,CCenter就是在Consul的基础上进行二次开发的配置中心。

微服务体系下配置的分类和组织形式

在实践中,不同产品线的配置会放置在Consul的不同路径下,实现不同产品线配置之间的隔离。


按照配置的用途,可将同一产品线下的配置分为三类:

1.API网关相关配置;

2.服务注册与发现相关配置;

3.应用相关配置。

其中,每类配置会对应Consul上的不同目录。


按照配置的变化特性,可将配置分为两类:

1.环境相关的全局配置

如MySQL等外部依赖相关的配置和其他与环境相关的配置,这类配置在开发测试生产环境中存在差异,需要为不同环境配置不同的值。
2.应用本身的配置

一般为不经常性发生变化、可动态调整、开关的配置。这类配置比较稳定,在初始化后,只有在需要时才会改动,通常会设置默认值。这两类配置在Consul上会放在不同的子目录下。这样QA、运维只需要关注环境差异部分即可。

基于以上对配置的分类,最终Consul上的Key的格式如下:

/ProductLine_Prefix/Usage_Prefix/Environmental_Correlation_Prefix/Config_Item_Path

其中,

ProductLine_Prefix:用来隔离不同产品线的配置;

Usage_Prefix:用来区分配置的用途;

Environmental_Correlation_Prefix:用来分隔与环境相关的配置;

Config_Item_Path:具体的配置项。

配置在Consul上的组织形式有以下两种:

1.以配置文件的形式组织,Consul上的一个K/V,对应一个配置文件,如nginx的配置文件。

2.以配置项的形式组织,将配置文件模板化,拆成一个个的配置项,每个配置项对应Consul上的一个K/V,多个配置项对应一个配置文件。大部分配置文件本身都是以K/V的形式组织的,均适合模板化,模板化后即可以按照配置项的特性,在Consul上分成不同的类别进行管理。

如何实现配置更新

Consul上的K/V,要如何生成可加载的应用,或可使用的配置呢?

1.用Node和Lua实现的微服务的配置更新,使用Consul-Template来实现;

2.用Java实现的微服务的配置更新,通过Consul-Template工具(需要重启应用)和在代码中引入Consul Client的依赖创建Watcher(热更新)这两种方式来实现。


Consul-Template如何使用?

Consul-Template是一个后台进程,它可以根据Watch Consul上K/V的变化,更新任意数量的模板,同时生成对应的文件,之后还可以运行任意的命令。要使用Consul-Template一般需要定义两个文件:

1.模板文件

模板文件一般按照Go Template的格式进行编写,示例如下:

config-tree.ctmpl:

{{ tree /consul/path/to/configFiles | explode | toJSONPretty }}

该模板在/consul/path/to/configFiles路径下的配置发生变化时,会渲染出一个Json格式的字符串,其中包含了/consul/path/to/configFiles下所有的K/V.

config-kv.ctmpl:

return {
host='{{ printf "%s/mysql/host" (env "CONSUL_CONFIG_PREFIX") | key }}',
port={{ keyOrDefault (printf "%s/mysql/port" (env "CON-SUL_CONFIG_PREFIX")) "" }},
user='{{ printf "%s/mysql/user" (env "CONSUL_CONFIG_PREFIX") | key }}',
password='{{ printf "%s/mysql/password" (env "CON-SUL_CONFIG_PREFIX") | key }}'
}

该模板是按照配置项来渲染的,在该模板中使用了Consul-Template定义两个方法key和keyOrDefault。其中,key会在Consul上对应的K/V创建后,再进行渲染模板;keyOrDefault则会在Consul上没有对应的K/V时,使用默认值代替。

模板中还使用了 " CONSUL_CONFIG_PREFIX " 这个环境变量,这样,不同的产品线便可以使用同一个模板文件,只需要修改" CONSUL_CONFIG_PREFIX "这个环境变量的值即可。

2.配置文件

配置文件是按照HashiCorp Configuration Language (HCL)编写的,示例如下:

template {
source = "config-tree.ctmpl",
destination = "config-tree.json",
command = "sh updateAndReload.sh config-tree.json”
} template {
source = "config-kv.ctmpl",
destination = "config-kv.lua",
command = "sh updateAndReload.sh config-kv.lua”
}

该配置文件的作用是使用" source"指定的两个模板文件进行渲染,将渲染的结果分别保存在" destination"指定的文件中,保存成功后,分别运行" command"指定的命令来更新并加载配置文件。


配置的更新方式

在个推的微服务体系中,配置的更新方式有两种:

1.替换配置文件,reload服务

2.调用服务接口直接更新内存中的配置

而在Java实现的微服务中,热更新配置通常是在代码中引入Consul Client的依赖,在应用启动时,会初始化一个Watcher来监听Consul上对应目录下K/V的变化,相关的K/V发生变化时,Watcher会负责将其拉取下来,然后调用相关的代码进行配置的更新。

基于Consul的二次开发-CCenter

配置中心CCenter在Consul上提供了更友好的WEB UI,并且增加版本控制,每次配置的更新都会生成一个版本,在应用版本后,配置才真正生效,可以更加方便地进行配置版本间的差异比较,应用任意版本的配置。

总结

以上就是个推在微服务实践中,基于Consul实现的一套配置管理的方案,作为轻量级的分布式K/V存储系统, Consul非常适合用于配置管理,可以帮助开发者们方便、快速地搭建配置中心,结合Consul-Template则可以方便地实现配置的实时更新,在Consul的基础上进行二次开发,实现了配置版本的有效控制,对微服务的配置管理起到了良好的辅助作用。

个推基于Consul的配置管理的更多相关文章

  1. QCon技术干货:个推基于Docker和Kubernetes的微服务实践

    2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevOps构成的云原生席卷整个IT界.在近期举办的QCon全球软件开发大会上, ...

  2. 基于Consul的数据库高可用架构

    几个月没有更新博客了,已经长草了,特意来除草.本次主要分享如何利用consul来实现redis以及mysql的高可用.以前的公司mysql是单机单实例,高可用MHA加vip就能搞定,新公司mysql是 ...

  3. 基于Consul的数据库高可用架构【转】

    几个月没有更新博客了,已经长草了,特意来除草.本次主要分享如何利用consul来实现redis以及mysql的高可用.以前的公司mysql是单机单实例,高可用MHA加vip就能搞定,新公司mysql是 ...

  4. Spring Cloud 基于Consul 实现配置服务

    Spring Cloud体系中提供了Config组件来进行配置服务管理.而Consul除了提供服务注册与发现功能外,同时也提供配置管理功能.本位将介绍如何结合Spring Cloud + Consul ...

  5. 一个基于Consul的.NET Leader选举类库

    前段时间有传言说Consul将不能在我国继续使用,后被查明是因法律问题Vault企业版产品不能在国内销售.Valut和Consul都是HashiCorp公司的产品,并且都推出了开源版本,继续使用开源版 ...

  6. 简单RPC框架-基于Consul的服务注册与发现

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  7. 基于consul高可用

    1.介绍consul Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License ...

  8. 基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现

    0.简介 0.1 什么是 Consul Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置. 这里所谓的服务,不仅仅包括常用的 Api 这些服务,也包括软件开发过程 ...

  9. 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁

    一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...

随机推荐

  1. Elasticsearch date 类型详解

    引言 一直对 elasticsearch 中的 date 类型认识比较模糊,而且在使用中又比较常见,这次决定多花些时间,彻底弄懂它,希望能对用到的同学提供帮助. 注意:本文测试使用是 elastics ...

  2. 内幕:XX二手车直卖网,狗屁直卖网,我来揭开他们套路!

    转自:明锐论坛   我是一位花生二手车直卖网的离职员工.已离职了一段时间,现在在某家汽车4S店公司上班.过去了那么久,每当看到他们铺天盖地的广告,心里都像十五个水桶--七上八下.思索已久,我还是决定鼓 ...

  3. React学习-React初识

    一.前言 为什么要去学习React呢,关于前端三大框架Angular,Vue,React其实都得去学吧,因为大家都在用啊,大家都再谈论啊,面试什么的都要求,没办法,曾几何时,大家都说求求大佬们别坑新了 ...

  4. JavaScript快速入门-ECMAScript本地对象(Date)

    JavaScript中的Date 对象用于处理日期和时间. var myDate=new Date()  #Date 对象会自动把当前日期和时间保存为其初始值. 一.Date对象的方法 方法 示例 n ...

  5. Android中级教程之----Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)

    在Android群里,经常会有人问我,Android Log是怎么用的,今天我就把从网上以及SDK里东拼西凑过来,让大家先一睹为快,希望对大家入门Android Log有一定的帮助. android. ...

  6. LeetCode-3.无重复字符的最长字串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  7. 机器学习之线性回归使用Python和tensorflow实现

    导入依赖包 import tensorflow as tf import numpy as np import matplotlib.pylab as plt from pylab import mp ...

  8. 关于go v1.11安装后出现不能正常运行测试程序的问题

    本人最近安装go1.11后出现上述问题,没有找到原因,可能之前安装过的旧的版本在windows下环境变量设置出现了问题,修改后仍然无效,后来删除所有安装版本,及go环境变量,重新下载1.10版本进行安 ...

  9. TCP三路握手,本质是一个通信原理相关的问题

    在通信系统中,最基本的信息的传递都需要两步,发送方发送的消息和对方的回复确认:A->B Send, B->A Reply(ACK).如果多接触一下其他行业的通信流程和规范,例如航空.铁路调 ...

  10. 了不起的Node.js--之四

    阻塞与非阻塞IO 绝大多数对node.js的讨论都把关注点放在了其处理高并发的能力上.Node框架给开发者提供了构建高性能网络应用的强大能力. 我使用的开发工具是Mac版的WebStorm,这个工具支 ...