一、vivo 从 0 到 1 的微服务架构工程实践
1.1 为什么需要微服务及落地挑战
伴随业务的高速发展,业务的复杂度越来越高,用户规模和访问量也越来越大;项目的迭代速度越来越快,交付效率要求也越来越高。与此同时,服务的集群规模越来越大,部署架构越来越复杂,故障范围也越来越不可控。此外,突增的业务流量时刻考验着服务的水平扩容能力,创新业务的快速孵化也对服务的可扩展性提出了更高的要求。想要解决以上问题,业务架构会朝着微服务架构方向演进。
正是在这样的背景下,vivo于2015年开始微服务架构改造,在落地过程中碰到了以下问题:
一是:服务数量多,配置修改生效、服务发布等变更场景效率低下;
二是:业务链路长,高可用保障难,问题与故障定位耗时长,服务的维护成本高;
三是:大量的跨服务通讯,性能和访问体验优化提升难度大;
四是:一个业务链路涉及大量的上下游团队,对接沟通的协作成本高;
为了解决以上落地过程中的开发、运维、团队协作等难题,我们需要建设配套的微服务架构技术体系。
1.2 vivo 微服务架构最佳实践-架构能力矩阵
建设一套微服务架构技术体系,助力业务又快又好地构建微服务工程,需要哪些技术能力?我们对微服务架构的主要业务场景进行了分析,在业务实践过程中,微服务主要会涉及同步、异步、定时任务三大核心业务场景。
在同步调用场景:涉及的技术能力主要是RPC框架、注册中心、服务治理;
在异步调用场景:涉及的技术能力主要是消息中间件;
在定时任务场景:涉及的技术能力主要是分布式任务调度。
除了上面介绍的框架和系统,业务在微服务架构改造过程中,需要的能力全貌是怎样的?
在深度参与业务微服务架构改造过程中,我们对最佳实践能力项进行了抽象,从而形成了vivo内部的微服务架构最佳实践总结-架构能力矩阵,总计近30项能力。为了更直观的呈现这些能力,我们从接入层、服务层、数据层的三层架构分层,开发、运维等DevOps的关键环节对架构能力进行了梳理,如下图所示。
图片
在开发环节:
在开发接口时,我们要实现内外网接口分离,保障接口的安全性,为此我们要接入网关来隔离内外网接口;在接入层和服务层,我们可以通过治理平台来实现限流、熔断、降级等能力,保障业务的高可用。
在构建内部服务时,我们要尽可能实现服务无状态,通过RPC框架实现内部接口的RPC相互调用,具备异常重试能力,提升服务的鲁棒性;在编码过程中,我们通过接入配置中心实现代码与配置分离,具备运行时动态调整配置的能力,提高服务的变更效率。
在异步调用场景,我们可以通过接入消息中间件实现业务间的相互解耦、流量削峰;在定时任务场景,我们可以通过分布式任务调度系统,实现失败任务的自动转移能力。
此外,我们可以通过落地存储与计算分离能力,实现服务层和数据层的解耦,便于分层扩容,具备面向未来更大规模业务的扩展能力。
在数据层,通过落地读写分离、冷热分离等能力,提升系统性能,节省存储成本;同时将这些能力通过研发框架进行封装,便于业务侧复用。
在运维环节:
我们可以借助CDN实现网站的动静分离访问,减小系统的请求压力;在日常运维过程中,我们要实现服务的可灰度、可回滚;服务节点无单点;同时借助容器技术快速实现弹性伸缩能力;提升系统的故障恢复速度。
在部署时,通过部署与发布分离,可以较好规避发布变更时产生的问题,即服务部署成功,并且健康检查通过后再发布到生产环境,减小故障的影响范围。
在遇到严重的系统故障时,需要具备使用备份数据从零恢复的能力,同时对所有已知的故障场景要有对应的预案,提升系统的故障应对能力。
在数据运维上,我们要确保数据属主唯一,避免多个业务对同一个数据库进行访问;同时也要实现业务数据和大数据的存储隔离,避免相互影响。
除了以上能力之外,我们还要实现业务的安全合规,建设覆盖Metric、Trace、Log的可观测能力体系,便于对故障问题的定位排查;在多机房层面,需要具备同城双活、异地多活等跨机房容灾能力。
1.3 vivo 微服务平台能力
为了更好落地以上最佳实践,我们构建了一套从接入层、服务层、消息层、框架层到存储层的平台能力,完整的平台能力地图如下图所示:
在接入层,我们提供了四层流量网关和七层微服务API网关;在服务层提供了服务/流量治理平台、配置中心、注册中心、接口管理平台、分布式任务调度等系统。
在消息层提供了消息中间件;在框架层提供了脚手架,可快速集成日志、配置、限流/熔断、MySQL/Redis等SDK,以及RPC框架。
在存储层提供了DaaS平台,包含MySQL、Redis、ElasticSearch、MongoDB、文件服务等系统能力。
为了更好排查故障问题,我们在可观测领域构建了监控中心、日志中心、调用链等系统;此外,还有更好支撑服务构建、变更发布的CICD系统和IT基础设施的配置管理系统CMDB。
截止2019年,vivo基本完成了从0到1的微服务平台能力烟囱式建设。
快速构建这些能力的过程,离不开开源组件的赋能。例如微服务API网关背后的zuul,注册中心背后的ZooKeeper和etcd,RPC框架的Dubbo和bRPC;配置中心的Apollo和Nacos,流量治理的hystrix和sentinel,消息中间件的RabbitMQ和RocketMQ,任务调度的xxl-job;如下图所示。
在此,我们也通过VDC(vivo 开发者大会)平台,感谢开源社区的赋能,助力vivo微服务架构技术体系从0到1的快速构建。
1.4 vivo 微服务现状
截止当前,vivo的微服务平台为全球分布在60+个国家/地区的5亿+用户提供服务;其中vivo现有万级的微服务,覆盖全网机器规模十万级,每天处理高达8000亿次的RPC调用次数,流量的峰值QPS达到千万级以上。
在支撑如此规模的微服务过程中,特别是在2020年以后,我们碰到了较多的问题与挑战,为了解决这些问题,我们使用了微服务引擎升级和统一平台建设的解决方案;下面来一起看看我们碰到了哪些问题与挑战?
二、微服务引擎升级与统一平台建设
2.1 面临的问题与挑战
我们知道,注册中心和配置中心是微服务架构领域的技术基石;下面给大家说明下我们在这两个基石系统实践过程中遇到的问题与挑战:
首先是注册中心,众所周知,ZK是CP特性,在注册中心场景有较多不可用的问题,此外还有跨机房多活能力缺失,集群故障半径大等问题;写性能无法水平扩展,在大规模Dubbo服务场景中,接口级注册模型注册的数据量大,在业务高频变更期间网卡的带宽峰值会超过1000Gbps。此外还有业务易混用,功能缺失;内部的多个技术栈使用不同的注册中心,跨技术栈调用的研发运维成本高等问题。
在配置中心场景,存在应用、组件配置的变更通道不统一,故障场景配置回滚慢,变更审计日志分散,业务恢复耗时长等问题;配置变更下发的时效不满足业务要求,内部存在多套配置中心,都需要和业务研发流程打通,存在审批、审计、回滚等功能没有对齐的问题;此外在功能和安全上,还需要实现内部的配置定时生效,配置加解密等需求,配置访问通道符合公司的安全要求。
从以上的问题与挑战中可以看出,基于开源组件快速构建的微服务底层引擎在vivo的内部业务场景中存在较多的可用性、性能&容量、研发运维、功能&安全问题与挑战。
2.2 注册中心引擎升级
为了解决以上的问题与挑战,我们需要进行技术升级,首先给大家介绍的是注册中心的解决方案:
针对Dubbo接口级服务发现导致ZK注册中心流量过大的问题,业界同行都在往应用级服务发现迁移来构建解决方案;通过Dubbo开源社区官网的介绍,我们可以看到,应用级服务发现是适应云原生,支持更大规模的服务发现模型;
将Dubbo接口级服务发现模型升级为应用级,可降低单机50%的内存消耗,降低注册中心集群90%的存储与推送压力,从架构上支持百万实例集群规模;
因此我们需要将Dubbo框架服务发现模型从接口级升级为应用级,彻底解决注册数据量大,对注册中心请求压力大的问题,同时具备面向云原生微服务架构的扩展能力。
此外,针对注册中心的可用性、性能&容量、研发运维等问题,我们需要建设满足AP特性、支持跨机房多活的统一注册中心,使用Session+Data分离架构,Data层持久化数据,Session层处理和客户端的长连接,无状态Session层能较好收敛客户端请求,实现读写流量隔离,具备较好的横向扩展能力,真正解决注册中心的性能、容量和扩展性问题。
综上,我们需要构建Dubbo应用级服务发现能力,构建Session+Data分离的统一注册中心,内部的项目代号为vns。
从上面的技术方案分析中,我们可以看到,通过应用级注册可以彻底解决注册中心的流量突刺问题;通过Session+Data双层分离架构可以实现业务无感知的多集群拆分,有效缩小故障半径,那如何来落地呢?
我们首先想到的就是上图左侧的技术方案,通过构建暴露gRPC协议、支持应用级注册的vns系统,海量的Dubbo服务通过双注册来实现迁移;但是在经过详细的技术分析之后,我们发现该方案存在明显的耦合问题:
首先是Dubbo应用级注册升级的进展依赖vns系统的建设进度,Dubbo框架依赖稳定的vns SDK,Dubbo框架和vns系统之间存在进度依赖问题;
其次还存在回滚依赖问题,当vns系统因灰度异常回滚时,Dubbo应用级注册升级进度也会同步回滚;
同理当Dubbo流量切换异常回滚时,vns的业务接入进度也会回退。
此外,部分不迭代的业务可能需要继续使用接口级注册,无法实现ZK注册中心的完全下线。
为了解决以上问题,我们对技术方案进行了升级,改用通过vns系统暴露和支持ZK协议,实现Dubbo应用级注册升级和vns系统的能力建设解耦;当vns系统的能力建设进展还未达到生产环境要求时,我们可以通过引入一套新的ZK集群来支持Dubbo的应用级注册模型升级;当vns的能力成熟度达到生产环境的要求后,可以对引入的ZK集群进行替代,整个过程可以根据系统建设进展和可用性保障要求,进行可控的灰度放量和回滚操作,控制变更风险;最终,vns通过暴露ZK+gRPC双协议满足业务的接入诉求。
在整个技术方案落地过程中,我们始终坚持业务导向原则,实现业务升级和迁移的零|低成本;采用稳妥、完善的升级迁移方案,确保过程可灰度、可回滚、可观测;大家可以看到,我们通过兼容ZK协议,最大限度的保障Dubbo业务的平滑升级,切换方案做到了可灰度可回滚可观测,在减少升级成本的同时,降低项目落地风险,最终实现ZK注册中心的完全下线。
2.3 配置中心引擎升级
介绍完注册中心,我们再来看看配置中心的解决方案,配置中心主要解决的是配置通道不统一,性能不达标,无法满足内部的业务需求等问题。
上图左侧是我们最新的配置中心技术架构图,右侧是统一配置通道的示意图,我们通过支持应用配置与组件配置的统一配置通道,实现了配置管理能力的收敛统一,在此基础上,建设一键审批/审计/回滚等能力,实现了和内部业务研发流程的打通,减少人力运维投入;此外,在新版配置中心上,我们也实现了较多的高可用、性能、安全、可观测能力增强等业务诉求;在配置中心升级过程中,我们追求业务的无感知升级,通过兼容原有配置中心对外开放的接口,实现了新系统的平滑升级,原有系统优雅下线。
大家可以看到,和注册中心的升级方案类似,在配置中心的技术方案设计中,我们也较好的遵循了业务导向原则。
2.4 统一微服务平台建设
介绍完注册中心和配置中心等微服务引擎的技术升级方案,我们再来看下从0到1快速构建的烟囱式微服务平台会面临哪些问题和挑战?
从上图左侧示意图中可以看到,我们快速构建的微服务平台存在10个以上的模块,每个模块都有独立的入口,用户使用平台的易用性很低;此外,这些模块在建设过程中,还需要重复对接云平台、单点登录、权限、工单、监控、CMDB等公共服务系统;系统审计日志分散,不便于快速定位因变更引起的问题;综上,烟囱式微服务平台存在多入口,功能重复对接,运维、研发成本高,故障排查与恢复效率低,易用性不足等问题。
要解决烟囱式微服务平台的问题,需要构建更合理的产品方案,我们对用户的使用现状进行了分析:
通过系统埋点数据发现,烟囱式微服务平台中用户使用频率最高的两个系统分别是配置中心、服务治理。
通过上图左侧的PV/UV饼状图数据,大家可以发现:
配置中心的用户访问主要集中在配置的【查询与变更】、【变更记录与审批】和配置变更相关的2个页面上,服务治理的用户访问主要集中在【服务概览】、【服务查询】和服务相关的2个页面上。
基于埋点数据,我们可以看到用户的访问集中在少数的几个功能上,通过整合各个系统模块高频使用的功能,建设统一的平台入口,实现系统间联动,这也给我们如何建设统一平台提供了较好的思路。
此外,在对各个模块的技术架构进行分析时,我们识别到了位于最底层、技术依赖程度最高的两个系统:配置中心、注册中心,这两个系统非常适合作为统一平台建设的技术底座。
区别于烟囱式微服务平台的多个系统模块独立对接CICD等研发平台,在统一微服务平台建设中,我们升级为统一平台对接CICD等研发平台;我们的建设思路是,以配置中心/注册中心为底座来建设统一微服务平台:
一是:基于统一的配置通道与CICD等研发平台系统进行联动,建设一键审批、回滚能力,整合研发流程,降低对接成本;
二是:通过统一平台的建设,实现平台间联动,建设高阶的自动化水平,支撑业务进一步提升持续服务能力。
2.5 引擎升级&统一平台建设总结
接下来,对我们前面讲到的内容做一个总结:在大规模、海量业务的微服务架构实践过程中,我们通过引擎升级和统一平台能力建设较好的解决了碰到的问题与挑战。
在升级和建设过程中,我们需要保证现有业务的连续性,保障不发生因底层引擎升级和平台建设导致的可用性问题。因此,引擎升级和统一平台建设的工作需要建立在高可用保障的基础上;换句话来说,可用性是我们所有工作的底座。
在这个基础上,我们实现注册中心和配置中心的引擎升级,完成应用级注册模型升级;在这个过程中,解决底层引擎的扩展性、容量、性能、可维护性和安全性等问题;最后,我们要建设统一的微服务平台能力,实现平台间联动,构建自动/自助化使用能力;赋能业务。
大家可以看到,通过完整的方案介绍,在上图右侧我们呈现了微服务架构实践过程中的价值分层逻辑,即在可用性的基础上,提升系统的扩展性、容量、性能、可维护、安全性等能力;然后再在此基础上,交付更高的研发效率,更好的用户使用体验。
三、微服务架构升级的总结与展望
介绍完我们的解决方案后,最后来说明下我们对微服务架构升级的总结与思考,以及对未来的展望。
3.1 拥抱开源的实用主义
在构建微服务架构技术体系的过程中,我们始终坚持拥抱开源,迭代业务适用的技术平台;结合内部业务的实际情况,我们走出了一条从开源到开源+自研的研发路径。
在从0到1的平台能力建设过程中,我们引入开源组件进行能力快速构建,快速交付满足业务的需求;始终坚持业务适用原则,不过度设计,支撑业务的快速迭代;以上阶段,我们称之为“拿来主义”。
在面向更大规模、海量业务实践过程中,为了解决碰到的问题与挑战,我们在开源的基础上进行增强,自研部分能力来解决亿级用户规模下内部业务的功能,性能,容量,研发流程打通等需求;这个阶段,我们称之为“实用主义”。
在技术平台迭代过程中,我们始终坚持2个原则,一是简单有效原则,坚持用最简单的解决方案来解决问题;二是迭代和演进原则,坚持平台持续迭代和演进的原则;前期基于开源组件快速搭建能力,再基于实际的业务需求和痛点来落地自研架构;在这个过程中,始终坚持业务适用,不为了技术而技术,避免大而全的技术架构。
此外,也要说明一个常见的误区,我们为什么不完全自研?vivo的微服务平台建设从开源社区获益良多,坚持不闭门造车,站在巨人肩膀上,持续引入优秀特性来支撑业务的快速发展,同时也会考虑将部分行业适用的通用优秀特性反馈给社区,和社区共同成长。
3.2 中间件组件全生命周期管理
大家可以看到,vivo的微服务架构技术体系引入了较多的开源组件,在实践过程中,我们摸索出了一套完整的中间件组件全生命周期管理策略。
我们先来看看业务的诉求和底层技术的特点:
首先是业务的诉求:
- 业务期望更高的迭代交付效率;
- 快速引入新技术,使用新技术助力业务创新,但很多时候新技术往往意味着成熟度不足,可能存在较多问题;
- 业务的不断创新与发展,对组件的性能、容量要求越来越高;
对业务来说,高效迭代交付需求是第一位的。
然而,底层技术有它自己的特点:
- 技术的发展有它的客观规律,需要经历萌芽期 → 膨胀期 → 低谷期→ 复苏期→ 成熟期等多个阶段;
- 缺乏约束的技术体系必然随着时间推移而腐化,治理不及时会成为技术债务,阻塞业务发展;
- 同类中间件组件的快速引入会有重复建设的效率问题;
- 中间件组件的技术升级周期客观上都比较长。
实践证明,只有足够稳健的底层技术能力才能更好支撑业务的高效迭代。在这个过程中,如何兼顾效率与质量?尊重客观规律,确保整个过程都有明确的目标和方向,避免走偏,慢就是快。
我们认为,完善的中间件组件全生命周期管理策略,首先需要在所有的技术团队中形成价值共识;再通过组件扫描和组件地图等手段及时对组件全貌进行洞察;在组件的标准化治理和运营阶段实现有规范,补短板;同时在新技术引入时,通过完善的新技术引入规范,覆盖功能/性能/容量/扩展性/成熟度/使用成本等维度;在组件的版本治理上,使用基线版本治理方案,输出明确的使用标准/版本升级方案/版本收敛策略;最后,在组件的成熟度管理上,我们可以借助Gartner(高德纳)技术成熟度说明和组件能力矩阵,不断提升组件的成熟度。
综上,为更高效的支撑业务,在组件管理上我们使用了更加入宽松的引入策略,同时也会对组件的全生命周期进行严格管理,践行宽入严出策略,通过完善的中间件组件全生命周期管理助力业务跑的更快,走的更远。
3.3 引擎升级探索
展望未来,我们会坚持和践行引擎升级和平台建设的持续迭代思路:
首先是对引擎升级的探索,通过引入新技术来解决当前碰到的研发效率、成本等痛点问题:
在研发效率方向,存在的痛点问题如下:
一是,组件SDK的升级周期长,碎片化问题严重;
二是,当前vivo内部主要的是Java、C++技术栈,新业务形态孵化可能会引入新的技术栈,需能够较好解决跨技术栈的问题。
想要较好的解决以上问题,需要探索基于Java Agent/SideCar技术的标准ServiceMesh模式,将RPC、MQ等中间件能力下沉,透明化实现微服务治理、高可用等能力增强,同时组件具备热升级能力。
此外,在成本方向,存在的痛点问题如下:
一是, MQ等重资源型应用的CPU、存储资源利用率差异大;
二是,部分事件驱动场景机器资源利用率低。
要解决以上问题,我们可以通过升级MQ组件,落地存算分离技术,探索计算存储资源利用率优化方案。另外,还可以探索Serverless技术,实现平台化托管运维,降低资源成本,天然适合小程序、快应用等事件驱动业务场景。
综上,在引擎升级探索上,我们会基于业务需求和痛点问题,探索和落地ServiceMesh/Serverless/存算分离等云原生技术。
3.4 平台建设探索
讲完引擎升级探索,我们再来看看在平台建设上的探索:
作为技术平台团队,我们在持续积极的探索“平台工程”理念,从现在的DevOps实践到平台工程,也是团队协作理念的再次升级。
我们知道,DevOps于2009年出现,2015年在国内火起来,它是一种文化、方法论,是敏捷理念从开发到运维的延伸。DevOps的理念是:践行谁构建谁运行,开发运维一体化,实现业务的高效交付。
但是,DevOps在实际落地过程中存在以下问题:
“DevOps团队”的中心化与去中心化取舍问题
【中心化】指的是,独立的DevOps团队,即不在业务团队中配置DevOps能力,而把DevOps人员集中起来组建团队,这种完全中心化的模式本质上和DevOps文化相矛盾。同时根据康威定律,可能会制造新的效能瓶颈。“独立的DevOps团队”在2014年被Thoughtworks“技术雷达”列为Hold (停止采用)。
【去中心化】指的是,将DevOps能力分散在业务团队,这种做法会将大量的和基础设施相关的工作职责划给业务团队;这种方式会随之出现基础设施和服务治理缺失、系统稳定性降低、研发和DevOps效能浪费等诸多问题。
因此,想要践行好DevOps,必须在中心化与去中心化之间取得平衡。
此外,从平台能力上讲,DevOps平台往往更侧重于建设流程和工具链,而在使用这些建设的工具技术平台过程中会大大增加业务开发团队的认知负荷,存在无法较好向业务开发团队屏蔽底层基础设施复杂性的问题。
平台工程的概念,是在2017年首次出现,于2022年在国内兴起。平台工程的定义是,一套用来构建和运营支持软件交付和生命周期管理的自助式内部开发者平台的机制和架构;它的特点是:平台在演进中提供足够的透明度、敏捷性,在建设过程中形成适合业务架构的高效协作模式。在这一过程中逐步将知识体系固化到平台中,从而使得工程方式标准化、流程化和规模化并持续改善;它践行的理念是:一个可用的、高效的平台并非一个技术团队埋头苦干就可以产出的;恰恰相反,一个成功的平台工程需要企业各个组织部门合作、协调、推广并根据实际使用反馈不断迭代。
在具体实践中,平台工程约定了“业务团队”和“平台团队”两个团队,其中“业务团队”负责业务研发,“平台团队”负责平台建设;“平台团队”通过将技术知识沉淀到“平台工程”,隐藏和抽象底层基础设施的复杂性,实现基础设施即代码,为“业务团队”赋能增效;同时,基于“业务团队”在使用“平台工程”的过程中的不断反馈来持续改进平台的自助化产品能力,构建一整套覆盖DevOps全链路的简单易用平台产品;可以看到,平台工程是一种最佳实践,和我们当前的团队协作模式匹配度非常高。
在平台建设的整体规划上:
当前阶段:我们构建的统一微服务平台会持续探索“平台工程”理念,沉淀配置中心、注册中心等平台的技术知识与最佳实践,构建和打磨业务自助化使用的平台能力。
展望未来:我们会通过明确的北极星指标,牵引平台提供更高的研发效率和更好的开发者体验。
在研发效率上,我们追求单位时间内更多的代码产出和需求交付;此外我们也追求更好的开发者体验,通过降低用户使用平台的打断次数和平台问题的人工支撑次数,提升业务团队和平台团队两个团队的开发体验。
在具体的落地路径上,我们始终以开发者用户为中心,针对研发工作中时间消耗较多的场景进行优化,通过北极星指标牵引,形成覆盖 IDE+PaaS 的平台工程实践路径,持续迭代优化平台能力,提升研发效率与开发者体验。