前不久作为架构师完成了某知名快消企业的一个业务中台建设 。系统上线后,经历了双十一活动的流量高峰,整体运行稳定 。最近有空,便将此次架构的思路,心得稍作整理在这篇博客中分享一下 。不会深入每一个技术细节,而是把用到的技术、框架、工具做一个简单的回顾,作为日后的参考 。
业务架构业务架构方面,该系统作为业务中台,主要负责客户资产管理,包括客户的卡、券以及其他虚拟资产 。通过对外暴露标准restful接口的方式提供服务 。服务的调用方包括自有渠道的App、小程序,以及合作伙伴渠道,包括招行、阿里等 。而系统本身也会通过服务网关去调用公司内部的其他业务系统接口,如通过客户中心接口同步会员信息等 。
文章插图
根据目前的统计,这个业务中台,每日的服务调用量在700万次左右,有活动时也会超过1000万次 。而大部分交易,发生在上班、午休以及下午3点左右(下午茶)的时间段内 。
文章插图
?
由于涉及到客户业务细节,这里对业务架构就不做详细说明了 。
技术架构这个案例中采用了基于SpringBoot的微服务架构 。结合企业自身的基础架构设施,进行K8S容器化部署,并采用Kong API Gateway对各业务中台暴露的API接口进行统一管理 。
Kong API Gateway随着微服务架构在企业中的流行,原来大而全的系统被拆分为粒度较小的中台,而系统中的大部分功能则被以restful API形式提供的服务所取代,这使得IT系统能够更加快速地响应业务变化带来的挑战,但同时随着服务的增加,如何有效管理这些服务却成为难题 。
文章插图
?
在一些中小型项目中,我们一般都会采用Spring Cloud的技术栈,并选择Spring Cloud Gateway来作服务网关 。然而,对于一些大型企业,则需要全局考虑服务的治理,网关性能,以及其他扩展功能 。
在这个案例中,企业使用了Kong作为API网关 。中台将需要开放外部使用的API,通过网关控制台进行注册,添加证书,生成Auth Key供关联方使用 。
Kong具有以下一些特性,能够很好地满足大型组织对于服务网关的需求:
- 开源(本案例中使用的是Kong的企业版,提供了原厂服务)
- 亚毫秒级的响应延迟,得益于基于Nginx与OpenResty带来的超高性能
- 单节点25K TPS
- 认证、授权、限流、数据转换(此案例中会员ID被添加到请求头中)、日志、统计分析
文章插图
?
应用架构整个系统采用JAVA开发后端以及vue开发前端,应用部分共分为4个服务组件,全部进行容器化部署,并通过Ingress Controller负载均衡对外暴露服务:
- 资产服务:提供客户资产相关的服务接口
- 资产消费者服务:MQ监听服务,异步处理资产相关请求
- 控制台服务:资产管理运维类服务接口,供控制台前端使用
- 控制台前端服务:使用Vue开发的控制台前端应用(如下图)
文章插图
?
SpringBoot除控制台前端外,其他三个组件均采用目前主流的java微服务框架SpringBoot 2.3.4开发(考虑到稳定性,未使用最新的2.4版本) 。
本案例中,通过开发应用框架,实现了系统中数据表达形式的统一,以及标准的据转换、校验、消息绑定、错误处理等功能 。架构师需要对应用框架负责,简明、高效、统一的应用框架,能够提升开发效率,产出标准一致的代码,保证交付质量 。
应用框架不在本文的讨论范围内,而以下一些技巧或第三方包,却在我们构建大多数SpringBoot应用中得到使用 。
####定制MyBatis 数据层框架采用MyBatis,在大型应用中MyBatis能够帮助程序员更好地控制数据层交互,并进行调优 。一般可以在applicaion.yml中配置MyBatis,但当我们需要让MyBatis支持更多定制特性(如:多数据库支持)时,可以通过定义SqlSessionFactory bean来实现 。
@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();sfb.setDataSource(dataSource);sfb.setVfs(SpringBootVFS.class);Properties props = new Properties();props.setProperty("dialect", dataConfiguration.getDialect());props.setProperty("reasonable", String.valueOf(dataConfiguration.isPageReasonable()));PageHelper pagePlugin = new PageHelper();pagePlugin.setProperties(props);Interceptor[] plugins = {pagePlugin};sfb.setPlugins(plugins);ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sfb.setMapperLocations(resolver.getResources("classpath*:mappers/"+ dataConfiguration.getDialect()+"/*.xml"));sfb.setTypeAliasesPackage("com.xxx.bl.core.data.model");SqlSessionFactory factory = sfb.getObject();factory.getConfiguration().setMapUnderscoreToCamelCase(true);//factory.getConfiguration().addInterceptor(new CoreResultSetHandler());factory.getConfiguration().setCallSettersOnNulls(dataConfiguration.isCallSettersOnNulls());return factory;}复制代码
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 防火墙基础与配置
- 萧何在汉书中属于 成也萧何败也萧何指的是西汉哪位开国功臣
- 朱元璋的郭宁莲是怎么死的 朱元璋老婆郭宁莲
- 哈尔科夫反击战的精妙之处
- 陈平和张良谁更会用计 陈平和张良谁的水平高
- 盗墓笔记里的汪家人是什么来历 盗墓笔记里的汪家人到底是什么人啊
- 这可能是网上最全的 Docker 工具集合
- 六安瓜片是怎么来的,六安瓜片的存储方法
- 一通百通,一文实现灵活的 K8S 基础架构
- 500元以内什么蓝牙耳机好?五大性价比高的蓝牙耳机推荐