PHP核心基础模块设计之浅谈配置中心

记得我刚毕业出来工作,在开会评审需求时,听到最多的是产品同事指着需求原型的某处说:“这个地方要支持可配置”。历经5年后,在另一家公司评审需求时,我很惊讶地发现这里的产品同事不再要求可配置,而是在需要改动某一句文案时,就要跑过来跟技术开发人员说,“快,这里帮我改一下!”。文案内容硬编程在代码中,改完后就立马发布上线。
关于配置,特别在系统中的配置,是一个大课题,由于篇章有限,并且关于配置的深入讲解已超出本书的范畴。所以,这里只作简单的讲解,以达到企业级系统开发的基本要求。

1 配置的分类

按照配置的性质,面向的使用人群和侧重点,配置可以分为两大类:技术类配置和业务类配置。
技术类配置很简单理解,即我们技术开发人员本身需要使用的配置。以下是一些技术配置的示例:缓存的时间,降级开关、多个图片域名的权重分配、新旧系统切换时的流量比例控制。这类配置,主要作用于系统,控制代码执行的方式,与业务无关。而业务类配置则是与业务有关,主要用于配置规则、条款、商品信息、文案、展示信息等,所使用的人群通过是产品人员、运营人员或商务人员。
拥有技术类配置,我们就可以随时对线上系统进行实时控制,性能调优,降级处理等。在发生突发情况时,不管是来自内部系统节点的故障,还是来自外部的攻击、流量涌进,都能做到“一切尽在掌握中”。这些技术类配置,仿佛构成了一个在线仪表盘,我们只需要轻轻点一下按钮,就能控制千里之外正在发生的事态。主动应对,而非被动接受。
提供业务类配置,同样也是意义重大的。通过业务类配置,我们往系统中注入了拥抱变化、充满活力、随时调配的特质。由于市场的变化,竞争对手的策略,或者是因为营销推广的需要,运营人员往往需要即时响应变化的系统;而政策的变动,或者伴随着体育时事、文化活动的举行,产品人员需要快速在关键环节增强引导或更新条款;对于供应商的优惠、战略合作伙伴的合同、或者投资方的要求,商务人员、公关人员等也需要系统支持各种动态数据的配置与呈现。
如果改动某处配置,原来需要两个人,通过使用配置后能减少到只需要一个人,那么这不仅仅是工作效率上的提升,更是赢得市场竞争力的所在。因为少一层阻塞,就能快一点响应。

2 两种实现模式

搭建配置中心,有两种实现模块。一种是分布式配置中心,一种是中央式配置中心。这两种模式,各有利弊,要根据自身系统和业务特点、关注点和约束和综合衡量选取。
分布式配置中心,可以避免单点故障,但面临如何保持配置一致性的问题。这种模式通常要结合“推模式”,即将新建的、或者更新的配置下发同步到各客户端系统。另一方面,中央式配置中心,很容易保持配置一致性,却容易存在单点故障的风险,并且客户端与服务端多次往回的通讯也会带来一定的性能损耗,增加了响应时间。

3 存储配置的方式

就使用PHP开发的系统而言,配置的存储方案,从最快到最慢,又可以分为四大类:

最慢:使用远程中央数据库
稍慢:使用高速缓存集群
稍快:使用本地缓存
最快:进驻内存

基本上按计算机操作系统的存储体系来划分的,最慢的是使用外部持久化的存储设备,例如这里的远程中央数据库。注意,这里着重标记了远程,是因为大型系统中,Web应用服务器往往都不只一台,并且应用服务器、数据库服务器会进行分层部署,并都在同一台服务器上。其次,是使用高速缓存集群,例如Redis集群、Memcache集群或其他NoSQL服务。更快一点的方式是使用本地缓存,主要有文件缓存、APCU缓存。最快的当数进驻内存的存储方式,这时可借助PHP扩展,或者自己实现的客户端、类库来配合实现,开发实现成本通常较高。

4 常见配置中心的架构设计

一种常见的配置中心架构是采用分布式实现模式,结合本地缓存,并提供业务类配置。它的组成部分主要有:

1、管理后台进行可视化操作,需要做好审计工作,以及权限控制等。
2、开放接口提供配置读取的接口,通常部署在内网,只开放给内部系统使用。
3、客户端接入SDK提供给客户端系统使用的SDK包,降低接入成本,同时便于统一管理、维护和升级。

这里不详细展开具体如何从头搭建,但对于上面这三部分,有一些注意的事项。首先,对于管理后台,要尽量做到可视化操作,因为使用此后台系统的人群是不懂技术的产品人员、运营人员、商务人员或者客服人员等。此外,还要做好审计纪录,要清晰的纪录什么时间、什么账号、改动了什么,包括修改前后的对比、改动的原因。纪录这些变更,将有助于我们在应对系统的变化时能快速知道缘由。当然,权限对于管理后台也是必不可少的,避免不必要的误操作。毕竟,权力越大,风险越大。
开放接口,只需要针对内部系统开放即可,这意味着可以只部署到内网,不需要向外部暴露。因为,通常这些业务配置都是公司内部的产品、系统和业务在使用,不会向外部透露。因此,提供接口的系统,应该要和管理后台分开部署。前面的管理后台,很明显商务人员下班回到家后也能在线操作的,而接口系统要求只能内部访问。注意到这一点很关键。最后一点,在客户端系统接入时,为每一个渠道分配一个标识也是很有必要的。随时后面系统越来越复杂,数量越来越多,清楚标识是哪个业务系统,将能帮助我们快速定位问题。
最后,客户端接入SDK也不是容忽视的部分。除了使用CUrl进行远程接口请求,做好超时或失败重试外,还要考虑使用本地缓存存储配置数据,提高系统响应速度。除此之外,还要注意对获取回来的配置数据,进行解析、转换和格式化,还要考虑默认值的管理。这样,即使是中央配置有异常,或者是人工录入有误,如果拥有了一定的容错性和健壮性,我们的系统在处于危险时期也能如期工作。这一点也是非常关键的。在正常的情况下,获取到配置只是完成状态,在异常情况下依然能保持系统正常工作,则是把事情做得更完善、更完美的体现。

发表评论