作为一家拥有 17 年历史的婚恋交友网站,珍爱网经历过业务规模爆发性增长,系统出现瓶颈,业务经历了微服务拆分、链路优化、上云、容器化、双云双活等发展历史,在每个技术环节都有相应的思考,在反复地暴露问题、解决问题之后,最终沉淀出一套珍爱特色的微服务治理架构。以下是珍爱网 CTO 彭万亮老师对架构的解读。
下图是珍爱网底层框架整体架构图,黄色部分是基础的工具类,项目公用的一些配置;紫色部分是扩展的插件,使用插件是因为涉及到流程控制,例如容器化、单元化、发布流程、日志(监控);蓝色部分是用的 Springboot 的快速启动方便大家接入项目中。
其中蓝色部分是珍爱网自研的组件,比如优雅停机,延迟回调,数据库缓存同步,上报,异步任务,字节码增强,调度任务;绿色部分是对优秀开源组件进行封装或者二次开发,对于数据库、缓存、队列、异步等的操作进行了管理,大大减少问题的发生次数。
服务框架层——微服务拆分
架构上独立业务一个服务,拆分的法则有很多,需要理论 + 经验 + 实践,大家需要注意的是,将业务改成树状的调用,去除网状层调用,另外需要验证实际效果,我们将 Spring Cloud 的 RPC 方案和 Dubbo 的 RPC 方案做了一下压测,Dubbo 的 TPS 的确优于 Spring Cloud,但是没有网上很多资料呈现的那么明显,实际效果和实验室效果存在差异,我们去做这个测试核心是让你能更好预估系统的能力。
网关层建设
除了本身核心路由功能外,还扩展了一些能力:基于 Sentinel 的熔断限流(进行二次开发),统一返回(出参入参标准化,包体结构,异常返回码),重试优化(Connect 的异常),优雅停机,启动预热。
数据框架层
第一个要做的就是数据层按照业务拆分,我们也是正好借用上云这个契机,整体需要做数据迁移,对数据重新规划。
第二,去除数据库中间层,为了提升性能和稳定性,引入 Sharding-JDBC(3.1.0,有些现在版本已经完善了),我们在底层框架上也提供了分库分表算法、ID 生成规则、路由工具类等工具,并且我们自研了一套配置管理,给我们后续的治理工作也带来了很大的便利,首先对于数据库的配置,我们希望统一进行管理,所有数据库配置在一个目录下面,交给架构组来维护,项目配置可以由业务团队负责(Nacos 实现),在 Git 上建了一个项目,里面是所有项目的数据库层配置,大家 Git 上提交配置之后,由架构组来发布,里面会涉及一些配置检查,尤其是分片规则的配置上,特别容易配置错,发布完成之后,我们通过对配置进行转换(二次开发),使用 ZK 监听让应用层和代理层做到同时的更新,为我们做大表无缝切换,带来了极大的便利,涉及到配置更新。
那怎么刷新数据库链接,如图所示:
里面会有坑,数据库瞬时面临翻倍的连接,对于本身连接数过高的数据库,会直接造成数据库崩溃,所以需要大家自己根据业务进行平衡。
另外一个常见的需求就是怎么把一张大表进行分表并且在不停机的情况下完成,全量数据采用 Dump 的方式,增量的数据我们通过 otter 同步数据,采用 ShardingProxy(上面配置分库分表规则)的方式写入到新表中,验证数据一致之后,我们把配置直接刷新,应用端便能直接切换完成,如果还有连接没有切换过来会怎么样,老的数据依旧会通过 ShardingProxy 写过去(现在 Sharding-Scaling),如图所示
另外我们还有一些和原作者的交流,有些他们不支持的地方,我们也做了一些二次开发,有些他们后续的版本也进行了采纳,比如一表多分片键(场景:动态表需要根据动态 ID 查询,也需要根据用户 ID 查询,避免了非分片建的全表扫描)、时间分片键如何做到不等式的路由(场景:日志业务,避免了区间查询的全表扫描),我们识别出分表键为时间,并且存在动态结构,也能自动定时创建表,我们经过调试发现性能上的问题。
服务治理层 发布框架
基于 Maven 的插件开发,自研 Zhenai-Dockerx-PlugIn 插件,让应用透明接入 Docker、Kubernetes。
参数校验,构建镜像,发布部署都由插件完成,开发只需执行 MVN Test 命令,便完成了容器化部署到测试环境,效率大大提升。
并行发布测试
微服务架构下,如何做到并行开发,需要有一套稳定服务,部署上只部署修改的分支涉及的微服务,通过 Zone 的方式进行流量染色,客户端可以通过在 Header 里面埋 Zone 的方式,也可以通过 Nginx 暴露固定 IP 生成 Zone 的方式,进行流量的全链路路由,另外要注意中间件也需要按照 Zone 进行路由。
发布流程改造
回到整个发布流程环节,开发人员只需要执行 MVN Test,其余的环节通过 Webhook 的钩子实现联动,在验收人员进行生成环境发布之后,会打一个正式的 tag,并触发钩子将正式环境也更新到测试的稳定服务中。
单元化改造
若一个业务引起了基础服务问题,那么将会影响到所有业务,利用容器部署的便利性,只要依赖单元化组件的项目,生产部署文件的同时增加项目名称,多运行一套环境,即可实现单元化,要注意的是注册中心正确路由和配置中心区分配置项,网关也同样需要单元化,后面甚至可以延伸到整个业务进行单元化。
双云架构
以上的内容仅是珍爱网微服务架构升级的一部分,实践过程中遇到过很多痛点,如业务技术发展很快却不知道如何切入到业务,需要沉淀了一套自己的微服务治理底层框架,只有把底层建设好了,才能支持技术和业务的多样性发展,后续用什么样的技术方案,只需扩展底层架构就行了。
更多细节,彭万亮老师会在将于 7 月份举办的 ArchSummit 全球架构师峰会(深圳站)2022 上详细阐述,希望帮助听众在面对一个庞大系统问题时,能够进行多维度分析与持续改进,同时,构建一套行之有效的自有架构。