阅读 773

分布式 配置中心

配置

配置(Configuration) 这个概念每个技术人都不陌生,可以说一个不提供几个配置参数的系统都不好意思上线跟别的系统打招呼。

究其本质是我们人类无法掌控和预知一切,映射到软件领域上,我们总是需要对系统的某些功能特性预留出一些控制的线头,以便我们在未来需要的时候,可以人为的拨弄这些线头从而控制系统的行为特征,我把它叫做 “系统运行时(runtime)飞行姿态的动态调整“。



静态配置

我们的系统存在一些外部依赖,这些依赖与业务无关,但是在开发阶段具有不确定性,我们通常会将这些配置在属性文件中,如数据库url,账户名,密码,等,这些配置项基本不会轻易改变,而且配置也简单,基本都是字符串,所以称他们为静态配置

所谓静态配置,就是在程序启动前一次性配好,启动时一次性生效,在程序运行期一般不会变化的配置。

具体包括:

  • 环境相关配置

有些配置是和环境相关的,每个环境的配置不一样,例如数据库、中间件和其它服务的连接字符串配置。这些配置一次性配好,运行期一般不变。

  • 安全配置

有些配置和安全相关,例如用户名,密码,访问令牌,许可证书等,这些也是一次性配好,运行期一般不变。因为涉及安全,相关信息一般需要加密存储,对配置访问需要权限控制。

动态配置

​ 我们在业务开发中,会提前预料到业务的不确定性,而产生的复杂的业务配置项,类型简单的可以使数字,字符,复杂点的可以是数组,map,以及其混合的组织形式,由于业务需求,会需要常常发生改变,这类配置项,我们称为动态配置。

所谓动态配置,就是在程序的运行期可以根据需要动态调整的配置。动态配置让应用行为和功能的调整变得更加灵活,是持续交付和 DevOps 的最佳实践。

  • 2.1 应用配置

和应用相关的配置,例如服务请求超时,线程池和队列的大小,缓存过期时间,数据库连接池的容量,日志输出级别,限流熔断阀值,服务安全黑白名单等。一般开发或者运维会根据应用的实际运行情况调整这些配置。

  • 2.2 业务配置

和业务相关的一些配置,例如促销规则,贷款额度,利率等业务参数,A/B 测试参数等。一般产品运营或开发人员会根据实际的业务需求,动态调整这些参数。

  • 2.3 功能开关

在英文中也称 Feature Flag/Toggle/Switch,简单的只有真假两个值,复杂的可以是多值参数。功能开关是 DevOps 的一种最佳实践,在运维中有很多应用场景,比如蓝绿部署,灰度开关,降级开关,主备切换开关,数据库迁移开关等。功能开关在国外互联网公司用得比较多,国内还没有普及开,所以我在下一节会给出一些功能开关的高级应用场景。

为什么要有配置中心呢

在单机时代,我们都是用配置文件来存储配置项。一个配置文件一般是一组配置项的集合或者叫配置集,一个系统根据逻辑模块划分,可以有1到多个配置文件。

在集中式开放时代,配置文件基本够用了,因为那是配置的管理通常不会成为一个很大的问题。如果要修改一个配置,登录到这台机器上,登录到这台生产机器上,vi配置这个配置文件,然后reload一下并不是很大的负担。

在分布式系统中,一次构建、发布、上线是非常非常重的一个过程,它不像单机时代那样重启一台机器、一个进程就可以了。

时效性

在分布式系统中,它涉及到将软件包(例如war)分发到可能超过几千台机器,然后将几千台机器上的应用进程一一重启这么一个过程,超过2000台机器的一个应用一次完整的发布过程需要多长时间,相信大家都一定会清楚,所以从时效性上来说,配置中心是势在必行。

统一管理

分发到几千台机器上,谁能保证几千次配置都会一致,不会有哪个人手误导致文件更改有错误,所以有一个应用统一管理管理配置,之后其他应用需要更改本地配置的时候,来向配置中心拉取,之后替换配置,之后重新发布就好了,这样就能保证所有机器上的配置的都一致。

分布式三项原则

在分布式计算技术的设计和实现中,CAP理论是一个重要的指导原则,其基本内容如下:

1、“C”是指一致性,即当一个Process(过程)修改了某个数据后,其他Process读取这是数据是,得到的是更新后的数据,但并不是所有系统都 可以做到这一点。例如,在一些并非严格要求一致性的系统中,后来的Process得到的数据可能还是修改之前的数据,或者需要等待一定时间后才能得到修改 之后的数据,这被成为“弱一致性”,最经典的应用就是DNS系统。当用户修改了DNS配置后,往往不会马上在全网更新,必定会有一个延迟,这个延迟被称为 “不一致窗口”,它的长度取决于系统的负载、冗余的个数等因素。但对于某些系统而言,一旦写入,后面读取的一定是修改后的数据,如银行账户信息,这被称为 “强一致性”。

2、“A”是指可用性。即系统总是能够为用户提供连续的服务能力。当用户发出请求是,系统能给出响应(成功或者失败),而且是立即给出响应,而不是等待其他事情完成才响应。如果需要等待某件事情完成才响应,那么“可用性”就不存在了。

3、“P”是指容错性。任何一个分布式计算系统都是由多个节点组成的。在正常情况下,节点与节点之间的通信是正常的。但是在某些情况下,节点之间的通信会 断开,这种断开成为“Partition”。在分布式计算的实现中,Partition是很常见的,因为节点不可能永远不出故障,尤其是对于跨物理地区的 海量存储系统而言,而容错性则可以保证如果只是系统中的部分节点不可用,那么相关的操作仍旧能够正常完成。

演进中的配置中心

经过上面的内容,大家知道肯定要有一个配置中心来统一管理,通过配置中心系统对每一条配置(每一个配置有唯一的配置ID)进行增删改查。区分不同环境的配置,每个环境同一配置ID对应不同数据库记录。配置最终以key-value储存在mysql数据库中。

1.

可以有一个配置中心,通过配置中心对每一条配置进行增删改查,配置最终以key-value储存在mysql数据库,配置对外服务,多机器部署,满足性能需要。应用直接去调用配置中心提供的接口查询配置,这样可能对数据库压力太大,这样的话可以在配置中心添加缓存,每次查询缓存,这样的话每次查询的时候,就不会调用数据库,每次可用直接查询缓存,每次更改配置的时候,顺便更改缓存,这样能保证可用性和一致性。

很多时候,这样可以基本上满足我们对配置系统的基本需求,对配置的增删改查,能容忍一段时间的数据不一致性。

这种设计,由于所有的配置都存放在集中式缓存中,这样集中式的缓存也会有他的性能瓶颈。而且,每次配置的访问都需要发起rpc请求(网络请求),因此考虑在客户端引入本地缓存(localCache,例如Ehcache)。


2.

能在服务端使用缓存,为什么不能再客户端使用缓存呢。

使用客户端缓存,那么缓存存在哪呢?

在客户端使用缓存可以分成三种,分布式缓存,内存和硬盘。

但是这三种各有利弊。

分布式缓存 那么网络资源的耗费没有得到节约,但是可以保证应用读取的配置一致性的保证。

内存 不用耗费网络资源,很快,但是重启会丢失配置

硬盘 不用耗费网络资源,不会丢失配置,相对来说会慢一些

考虑到,减少网络请求的因素,在客户端引入localcache,虽然内存和硬盘可以节省网络资源,但是内存和硬盘都存在各自的缺点,那么我们可以采用内存+硬盘的格式,把资源保存再硬盘里,每次重启时在从硬盘中读取之后加载到内存中。这样的话来解决系统的高可用,高性能、可伸缩性。

一致性的话的我们可以采用缩短更新缓存的问题来解决。也可以通过配置中心通知应用配置更新,应用从配置中心拉取最新的配置、更新本地配置并通知到应用。



php与配置中心

与c#、Java、Go、Python、Node.JS等等应用不同,php的程序不支持常驻内存,php每处理完一个请求后,资源都会被释放掉;这也就意味着如果我们在请求进来时,都需要去访问配置中心获得各种配置信息。

因为配置中心是外部程序,每次访问都是跨进程通讯;假设获取一个配置需要耗时1ms,那么一百项配置就是0.1s;这是巨大的潜在性能影响

因为php的动态性,我们可以使用动态生成php文件的形式来做缓存。我们也可以使用类似confd这样的工具做去监控watch配置中心中各个值。在值发生变更时,便触发脚本去删除掉缓存文件,那么下次程序再调用get_key函数时,便会自动去配置中心获得新值,并重新缓存。



关注下面的标签,发现更多相似文章
评论