掘金 后端 ( ) • 2024-07-01 15:40

一、背景

在当今快速发展的数字化时代,企业面临着日益复杂和庞大的软件应用系统,传统的单体应用程序已经无法满足金融行业日益增长的需求。微服务架构应运而生,微服务架构具有更好的可伸缩性、灵活性和容错性,并成为金融届优化业务流程、提高效率的重要解决方案。

中原银行于2018年开始进行微服务平台的自主研发,为微服务运行时治理提供一站式全生命周期解决方案,为全行微服务应用提供高性能、高可靠的平台级支撑。平台已支撑337个微服计1365个节点,网关日交易量超1亿次,微服务系统间日交易量超2亿次,为全行信息系统的分布式架构转型奠定坚实基础。

目前平台已经在生产环境平稳运行了4年,在流量治理、可观测等方面得到了大幅提升,但在持续迭代过程中因平台基础框架Spring Cloud版本限制出现如下痛点:

  • 云原生场景支撑能力有限:目前全行大部分微服务都已经迁移到容器云环境,但服务依赖的底层SDK Spring Cloud框架对云环境感知力度不足,拓展难度高,适配云原生场景较为困难;
  • 业务新产品对接改造量大:新采购系统适配高版本Spring Cloud,接入我行微服务平台,需要进行版本降级改造,人力资源投入高。
  • 疑难问题难以求助社区:平台一直在Spring Cloud Finchley版本上迭代开发,社区在2019年已不再维护,疑难问题无法通过社区寻求帮助

二、版本升级带来的挑战

因此我行微服务平台启动了Spring Cloud大版本升级工作。经过前期充分调研,发现在如下几个方面存在挑战:

1.Spring Cloud新特性的兼容

微服务平台Spring Cloud Finchley版本自2018年起至今已经经历6个大版本的更新迭代,期间自Spring Cloud 2020起官方修改了Spring Cloud版本的命名。
Spring Cloud各个版本发布时间:

从官方文档分析,经过六个版本的技术演进,Spring Cloud框架已至少在6大方面进行了相关能力提升:

上述仅列举主要功能,Spring Cloud集成了分布式应用所需的一系列服务治理及中间件相关框架,大版本升级代表相关框架的大升级,那么将会带来如下两个问题:

  • 上述新特性如何合理引入平台框架中?
  • 升级内容会不会与平台存量功能和行内规范发生冲突?

2. 服务治理技术栈的切换

Spring Cloud提供统一规范和接口,目前Spring Cloud中主要有三套服务治理实现的底层框架,Spring Cloud Netflix、Spring Cloud Alibaba以及Spring Cloud官方的实现;

Spring Cloud Netflix是最早的底层实现,Spring Cloud最初的Dalston版本就由该框架实现,但随着后续技术发展,新技术更新迭代,像Spring Cloud Alibaba等优秀的开源框架迭出,Spring Cloud Netflix的发展也来到了瓶颈,在Spring Cloud Greenwich版本中宣布进入维护期,Spring Cloud 2020版本中正式删除Netflix大部分组件,因此我们需要解决如下两个问题

  • 是否需要切换Spring Cloud Netflix技术栈?
  • 用什么技术栈来代替呢?

2. 存量系统升级迁移

作为技术中台,确保业务连续性和尽可能的减少业务侵入性是必需考虑的一环,在微服务系统研发生命周期中主要包括两部分

一类是开发态,微服务应用在运行时产生的运行配置和服务治理规则如何处理?,开发态中提供给业务应用模板工程是否需要调整?,SpringCloud在版本更新中对Spring循环依赖、配置文件Bootstrap加载模式、spring.factories初始化规则都做了调整,上述变化是否需要兼容; 一类是运行态,微服务应用在运行时产生的运行配置和服务治理规则如何处理?

三、Spring Cloud升级实战

根据上述的痛点、问题和挑战,我们进行了深入的分析,总结出如下几个维度的思考域,并设计相关技术方案用以进行落地工作;

1. 明确升级目标

确定版本

首先我们统计了Spring Cloud各个版本的新功能,新特性和升级要求,虽然Spring Cloud官方提供了spring-boot-properties-migrator模块协助升级,但实际上对跨多个大版本帮助有限,例如Spring相关参数还是需要经过大量测试验证,考虑根据行内业务实际情况,我们基于以下两点进行了思考:

  • JDK8适配性,行内大多数应用基础环境依赖于JDK8,行内目前也正在探索JDK升级可行性,为了保障平台通用性,Spring Cloud需要兼容JDK8;
  • 生产稳定性,新版本虽然功能性更突出,但需要考虑其生产稳定性,我们倾向于发布1-2年的次新版本; 综上因素,我们选择了Spring Cloud 2021 + Spring Boot 2.7.9作为升级目标。

确定升级范围

其次对于注册中心、配置中心、认证中心等中心化应用的升级我们一直慎之又慎,经过调研,Eureka 2.0新版本主要以兼容Spring Boot 3.x为主,未提供新功能(需要注意的是Eureka Client 新版本中使用RestTemplate替换Jersey,功能性不受影响),Apollo配置中心具备升级潜力,但存量迁移风险较大大,后续考虑试点应用,因此,本次升级范围计划为微服务底层框架 + 多版本管理能力建设。

**调研技术栈演进
**

目前平台很多定制化功能基于Spring Cloud Netflix,但在Spring Cloud 2021版本中官方移除了绝大部分Spring Cloud Netflix的组件依赖,为了减少升级成本,额外考虑了是否可以重新引入相关依赖,不进行技术栈切换,调研结论是在Spring Cloud Hoxton后已经无法使用Spring Cloud Netflix,因此在后续我们进行了技术栈选型工作

Spring Cloud Netflix技术演进:

2. 选型技术框架

对于Spring Cloud Netflix的代替方案,Spring Cloud官方提供了建议,但根据框架功能性、稳定性等方面考虑,我们融合了原生Spring Cloud生态和Spring Cloud Alibaba的功能优势,使用下列实现:

  • 在配置管理上沿用Apollo作为配置管理中心,采用Apollo直接与SDK中Spring集成的方式进行动态配置更新,舍弃Netflix Archaius,简化配置管理流程;
  • 在服务通讯上保持OpenFeign的模板调用方式不变;
  • 在负载均衡上使用Spring Cloud官方推荐Spring Cloud Loadbalancer框架,跟进社区技术演进;
  • 在熔断上采用Spring Cloud官方推荐的门面框架CircuitBreaker和Spring Cloud Alibaba Sentinel的结合模式,保持开源规范的同时,引入Sentinel更丰富的服务治理场景;
  • 在限流上采用Spring Cloud Alibaba Sentinel代替Guava库,丰富限流治理策略的多样性。

3. 改造&创新

基于Spring Cloud生态可扩展性进行创新,新增支持同中心优先、基于权重的灰度发布、动态服务级接口级超时控制、服务隔离、接口黑白名单等在金融场景下高频使用的服务治理能力,下面介绍部分技术实现:

灰度发布

灰度发布功能细化分为同中心优先、版本亲和、权重灰度、负载均衡四部分,SpringCloud Loadbalancer提供可插拔的基于服务发现的服务列表过滤机制,且对同中心优先和权重灰度有部分支持,但存在字段、过滤流程限制,因此,在此基础上进行了扩展创新,且开源框架中默认要求开启缓存机制,经过性能测试实践,与EurekaClient缓存冗余,也进行了优化;

云环境优雅下线

SpringBoot2.3以上版本官方提供了解决方案,但开源方案存在部分问题:

  • Eureka的下线操作晚于Web容器停止接受新请求,会导致部分流量失败(返回503);
  • 无论是否区分管理端口,actuator接口都将无法使用。

因此我们在开源基础上进行优化,在web容器停止新请求之前,插入自定义的生命周期实现,提前通知Eureka下线,并阻塞web容器等待Eureka信息同步,等上游无法发现该实例后,再进入框架的下线逻辑。

监控指标增强

Spring Boot原生actuator包提供API、JVM监控指标,但并不满足实际生产需要,因此我们在框架内对原生监控数据进行了扩展,主要包括以下内容:

  • 多维度API指标,新增P95/P90请求耗时分布、请求来源等信息,并提供了URL上限、功能开关等容错参数;
  • Web线程池指标,基于Undertow JMXBean弥补了开源Undertow线程池指标的空缺;
  • 微服务状态指标,支持感知云环境及SDK版本等信息,方便进行多版本管理;
  • 其他包括Spring Schedule框架、服务熔断等相关指标,并提供扩展接口,支持业务应用进行自定义。

监控面板展示:

SDK模块化、Starter化

在原有SDK基础上对SDK进行了模块化、Starter化改造,全面基于Spring Cloud标准自动装配机制进行功能扩展,充分利用Spring特性,将平台能力构建与开源框架之上,对业务系统屏蔽底层实现,此外根据服务治理能力将SDK拆分为以下几个模块:

  • 通讯模块
  • 熔断模块
  • 限流模块
  • 灰度模块
  • 认证模块

各个模块支持独立引入,提供对应的容错开关,丰富业务应用接入场景,降低生产问题爆炸半径,提高生产运行稳定性;

4. 管理运维

为了解决存量应用升级和多版本管理的问题,新版本微服务框架兼容存量配置项,统一管理平台采用双写模式兼容两套服务治理体系,将服务治理策略同时下发,业务应用迁移时,业务应用仅需按照升级指南修改依赖和进行重点功能测试即可完成升级。

提供工程模板

对于行内新接入的业务应用,行内统一开发平台提供新版本的模板工程,业务系统研发人员可一键建设工程,缩短研发周期,统一行内标准规范。

四、性能提升

Spring Cloud 从 Finchley 版本升级到 2021 版本带来了许多改进和优化,在性能上主要是优化启动速度和优化负载均衡器分发能力;

1、优化启动速度

(一)注解索引算法优化 在 Spring Framework 5 中,新增@Indexed 注解,主要作用是提高注解处理的性能,在编译期将注解类型的索引信息存储在 META-INF/spring.components 文件中,使得类路径扫描时无需逐个检查每个类文件是否包含特定的注解。
 (二)@Configuration优化 在@Configuration 注解中新增新属性proxyBeanMethods,该属性用于控制@Configuration类中方法的代理行为,之前Spring 使用CGLIB代理来处理配置类的@Bean方法。这意味着每次调用@Bean方法时,会默认返回单例,新版本中可以设置proxyBeanMethods属性为false,通过禁用CGLIB代理来减少性能开销。

2、负载均衡器优化

Spring Cloud LoadBalancer使用Spring WebFlux的响应式编程模型,可以更好地处理高并发和大规模请求。相比之下,Ribbon 使用的是同步阻塞模型,由于响应式编程模型的非阻塞特性,Spring Cloud LoadBalancer 可以提供更高的吞吐量和更低的请求延迟。以及更高效地利用线程资源,避免了由于阻塞操作导致的线程资源浪费,从而提升了整体性能。

3、性能测试

**启动速度对比:**可以看到启动速度上经过SpringCloud新版本新特性优化及SDK改造,启动速度获得了提升。

性能对比:

在模拟真实业务多接口混合测试场景中,

  • 升级新版本SpringCloud的sdk后,在不同并发数下,性能获得了5-10%不同程度的提升。

  • 原生SpringCloud和SDK版本的性能基本一致,SDK内部逻辑对交易影响,

五、总结&展望

中原银行微服务平台经过发掘自身痛点和业务诉求出发,确立了Spring Cloud大版本升级需求;并在平台侧、业务侧两个维度将Spring Cloud大版本升级工作进行了细化拆分,按照确立目标、技术选型、改造创新、管理运维四个模块的实施路径进行技术攻坚,最终实现平台底层重要框架-Spring Cloud的大版本升级工作,平台在升级后,在稳定性、扩展性和对容器云的支撑能力等方面都得到了较大的提升,为我行数智转型提供强有力的底层支撑。

未来我们持续深入跟进Spring Cloud生态发展,探索周期性升级计划的可行性,避免因为过长时间版本差异导致后续升级困难,紧抓Spring Cloud与Kubernetes、Docker等云原生技术的结合,探索Spring Cloud生态的发展新趋势,从实际业务应用的诉求中提取更加场景化的新特性、新能力,同时加强与开源社区的合作交流,深耕金融领域科技能力,助力全行数字化转型创新发展。