一、缘起
随着业务越来越复杂,用户量与流量越来越大,“服务化分层”是架构演进的必由之路,此时:
- 站点应用会调用服务,上游服务调用底层服务,依赖关系会变得非常复杂;
- 对于同一个服务,为了保证高可用,服务会由若干个节点形成集群;
如上图所示,用户中心us有三个节点,ip1/ip2/ip3组成集群对上游提供服务,保证高可用。
那么问题来了,当服务集群增减节点的时候,是否存在“反向依赖”,是否“耦合”,是否上游调用方需要修改配置重启,是否能做到上游无感知,是今天需要讨论的问题。
二、配置私藏
“配置私藏”是配置文件架构的最初级阶段,上游调用下游,每个上游都有一个专属的私有配置文件,记录被调用下游集群配置信息。
如上图:
- 用户中心us有ip1/ip2/ip3三个节点;
- service1调用us,它有一个专属配置文件s1.conf,配置了us的集群信息ip1/ip2/ip3;
- service2也调用us,也有个配置文件s2.conf,也配置了us集群信息ip1/ip2/ip3;
- web2调用us,同理w2.conf,配置了us集群信息ip1/ip2/ip3;
是不是很熟悉?
这是典型的“配置私藏”架构,很多公司初期都是这么玩的。
1. 配置私藏架构的缺点是什么呢?
此时,有两大痛点:
问题一,调用方很痛:us集群发生变化的时候,s1s2web2需要修改自己的专属配置文件,并重启。
画外音:这是一个典型的“反向依赖”耦合,集群变化的是你,凭啥修改配置重启的是我,需要优化。
问题二,服务方很痛:us不知道有多少个上游调用了自己,无法进行服务治理。例如:它无法按照调用方限流,容易出现一个边缘上游业务把调用量打满,从而耦合影响上游核心业务。
2. 那要怎么优化呢?
架构的升级并不是一步到位的,可以先采用最低成本的“全局配置法”,来解决问题一。
三、全局配置
“全局配置”法:对于通用的服务,建立全局配置文件,消除配置私藏:
- 运维层面制定规范,新建全局配置文件,global.conf;
- 对于服务方,如果是通用的服务,集群信息配置在global.conf里
- 对于调用方,调用方禁止配置私藏,必须从global.conf里读取通用下游配置
1. 有什么好处?
- 如果下游容量变化,只需要修改一处配置global.conf,而不需要各个上游修改;
- 调用方下一次重启的时候,自动迁移到扩容后的集群上来了;
- 修改成本非常小,读取配置文件目录变了;
不足:如果调用方一直不重启,就没有办法将流量迁移到新集群上去了。
2. 有没有方面实现自动流量迁移呢?
答案是肯定的,只需要实现两个并不复杂的组件:
(1) 组件一,文件监控组件:FileMonitor
作用是监控文件的变化,起一个timer,定期监控文件的ModifyTime或者md5就能轻松实现,当文件变化后,实施回调。
(2) 组件二,动态连接池组件:DynamicConnectionPool
“连接池组件”是RPC-client中的一个子组件,用来维护与多个RPC-server节点之间的连接。所谓“动态连接池”,是指连接池中的连接可以动态增加和减少。
这两个组件完成后:
- 一旦全局配置文件变化,文件监控组件实施回调;
- 动态连接池组件配置配置的变化,动态增减连接,自动完成下游节点的增容与缩容。
全局配置文件是一个能够快速落地的,解决“修改配置重启”问题的方案,但它仍然解决不了,服务提供方“服务治理”的问题,此时可以采用“配置中心”来解决。
四、配置中心
对比“全局配置”与“配置中心”的架构图,配置由静态文件升级为动态服务:
- 整个配置中心子系统由zk、conf-center服务,DB配置存储,conf-web配置后台组成;
- 所有下游服务的配置,通过后台设置在配置中心里;
- 所有上游需要拉取配置,需要去配置中心注册,拉取下游服务配置信息(ip1/ip2/ip3);
当下游服务容量变化时,配置中心会将集群的变化信息推送给上游调用方,再结合动态连接池组件,完成自动的扩容与缩容。同时,有了全局的调用拓扑图,很容易实现按需限流,蓝绿部署,算法分流等服务治理高级功能。
不足:系统复杂度相对较高,对配置中心的可靠性要求较高,一处挂全局挂。
五、总结
1. 系列方案解决什么问题?
配置导致系统耦合,架构反向依赖。
2. 什么痛点?
- 上游痛:扩容的是下游,改配置重启的是上游
- 下游痛:不知道谁依赖于自己
3. 配置架构如何演进?
- 配置私藏
- 全局配置文件
- 配置中心
知其然,知其所以然。
思路比结论更重要。