浅谈 BSS3.0 产品“守成”之策上 • 架构提升篇
贞观十年,唐太宗谓侍臣曰:“帝王之业,草创与守成孰难?”对于唐太宗的问题,魏征与房玄龄从各自的角度出发,阐述了自己的观点。虽然太宗认为两人说得都对,但最后还是认为当前形势当以“守成”为重。
2017-2019 年,BSS3.0 版本相继在湖南、重庆、新疆、甘肃、江西、青海、广西 7 个省份上线,渡过了一个大规模的交付期,可谓“草创”期已经顺利完成。从 2020 年开始,正式进入 BSS3.0 运营期,由“草创”期转变到“守成”期。在这期间我们更侧重产品的稳定运营,以及通过产品的不断提升和优化,持续巩固产品建设成果。
为了保障成果能够顺利达成,我们设定了几个目标:
产品在架构上进行优化提升,引入行业成熟的组件提升系统处理效率;
系统性能优化要在现有基础上至少提升 50%以上;
运维要更具备体系化建设,具备可视化运维能力。
“守成”路上,我们做了什么?
深入现场,了解发现并解决客户的痛点
客户的诉求和愿景是产品前进的动力因素之一。随着行业趋势的变化、用户需求的不断更新,过去被人们“想当然”认为是痛点的内容,很快可能就不再是痛点。而在新的业务驱动下, 适应新的业务变化则会变成客户的重点诉求或痛点。
为此,我们一方面按季度搜集几个省份 TOP3 产品优化提升的问题,另一方面深入省份地市一线进行走访,了解一线人员在系统使用上的一些痛点和诉求。最终在半年时间内,我们总共梳理出 27 个系统优化提升的专题,根据收集的痛点和诉求,归类分析后大致有以下几类:
1)操作友好性方面:目前电信业务更多的侧重在融合类业务,业务支撑灵活性不够,一线人员操作复杂,业务办理效率低;
2)架构方面:中心间、业务功能模块间相互调用效率低,处理能力存在瓶颈;
3)性能方面:业务需求不断迭代后,系统经常出现慢的现象;
4)运维方面:无可视化运维手段,系统运维模式陈旧,没有数字化运维体系,运维效率低。
深入分析,从根本上去提升产品竞争力
本着新兴业务加速“长”,存量业务加速“强”的原则,我们对收集的重点专题需求和问题按照类型将其分解成了 3 个主要方向的优化路径:
1、从架构上优化,使产品的“筋骨”更加健壮。
产品包统一,核心规则统一:让省份的版本在方案、研发投入上能够保持一致,提升产品质量及交付效率;
技术组件引入:自动竣工模块引入消息中间件、销售品检索、日志埋点引入 ElasticSearch 等;
引入 Nacos 统一配置中心:将系统参数、开关、提示信息等内容进行统一管理,提供可视化管理功能。
2、从性能上优化,使产品的“血液”更加鲜活。
异步处理提高效率:在订单处理环节,将集团上行接口部分进行异步处理,省内、集团同时并发,提升系统的处理性能;
规则并发处理:在产品属性规则、订单处理规则部分,区分校验类规则和计算类规则,对校验类规则实行并发处理机制,优化并发处理效率;
业务模块优化:对极简受理转单重构专题等功能进行代码重构,调整受理流程和逻辑,简化受理过程;
标准化管理:在整治慢 SQL 过程中,对 SQL 语句的编写提出规范化要求,序列的管理进行统一管理和输出;
业务实现优化:针对复杂的业务,提供礼包配置及礼包受理模式,实现业务组合打包模式,为业务的创新和扩展性提供更灵活的支撑模式;
业务重构:对政企类大客户受理,梳理新的受理流程和处理逻辑,让政企大客户受理不再成为“顽疾”。
3、从运维上优化,使产品的运维能力更加健全
缓存优化:提升缓存刷新效率,提供缓存可视化查看界面;
日志编码规范化:对日志进行分类,提供规范化的编码格式,实现日志可统计、可分析,根据日志数据进行统计分析,提升运维数字化能力;
日志埋点:对系统提供的服务进行埋点,实现服务可监控,可追踪;
服务流量监控:更高效地保证系统的正常稳定运行,保障网络安全。
深入实践,落实产品优化方案
实践是检验真理的唯一标准,在完成需求收集、方案设计工作后,我们按照架构、性能、运维三方面进行产品提升改造工作,分三个篇章介绍 BSS3.0 的优化之路,期待能够将部分“经验之谈”共享给大家,也希望与读者进行更深刻并且细致的探讨。
产品能力集约化
我司 BSS3.0 业务遍布全国东南西北各个省份,正如祖国大江南北各地的人文习惯不一,各省的业务也不尽相同。而如果一个产品需求都完全按照各省的业务进行设计,必将在产品统一建设的道路上逐步变得不可控,同时在产品方案、研发人员投入上会消耗更多的人力。因此,我们按照产品业务特性,重新将产品分为核心能力层、产品能力层和定制业务能力层,将集团和省份的共性业务逻辑提炼出来承接到产品能力层,从而保证后续集团和省份的共性需求可以实现一个方案、一次改造、整体交付的产品研发模式。
代码架构示意图
如图所示,我们产品工程结构主要分为定制业务能力层(简称定制包)、产品能力层(简称产品包)、核心能力层(简称核心包)。核心包和产品包在各省是统一,定制包则按照各省的情况进行分支管理。其中定制包与产品包都包含 web 层和 service 层,核心包只有 service 层(提供核心功能 API)。在三层结构中,定制包需要依赖产品包,产品包需要依赖核心包,但是定制包不能直接依赖核心包。各层实现的主要逻辑如下:
定制包层:主要负责各省个性化的业务需求实现,该层中完全可以按照省份的要求进行定制研发,提供个性化服务。
产品包层:主要负责通用业务的实现逻辑处理,如电信省份的礼包受理、产品属性处理等公共逻辑;
核心包层:主要提供产品的核心功能实现,如产品实例的处理、订单保存处理、订单算费等逻辑。
在完成产品能力集约化管理后,对于电信集团的需求和省份的共性提升需求,我们将 90%的改造工作量集中在产品包和核心包。保证了一个需求只需要一个方案,一次开发就能几个省份全部共用,由此带来的人员投入相比集约化前减少了 53%以上。
消息中间件引入
引入消息中间件的好处可以起到抗高并发,异步,削峰,业务解耦的作用。
产品现状:营业员经过客户资料验证、套餐选购、订单录入、订单保存、订单提交一系列流程之后,受理过程的最后一个环节是订单竣工。优化前,订单竣工采用的是接口队列表的方式,使用 LinkedBlockingQueue 将所有的订单都先放入同一台机器的竣工内存池中,再依照先进先出原则执行最终的竣工逻辑。若该机器出现异常时,将造成订单严重的积压,后果不堪设想。同时,竣工队列的机器作为远程机,竣工处理和竣工队列都是采用的远程调用模式,订单处理性能上也存在瓶颈。
改造前订单竣工处理示意图
基于消息中间件抗高并发、异步的优点,结合订单竣工的处理逻辑。我们引入了中国电信云平台 CTGMQ 消息中间件,将待处理的订单按优先级分类后,通过生产者产生竣工消息队列发送到消息中间件,消费者消费按对应主题消费数据,异步调用原有竣工逻辑将订单竣工并记录生产、消费日志。订单处理引入消息队列后,体现了以下优势:
实现服务限流,提高服务稳定性(将请求缓冲起来,降低并发请求保障服务正常运行);
实现解耦,降低系统耦合度(生产者和消费者解耦设计);
增强了系统的扩展能力,业务量增多时,可以随时增加消费者来处理,从而可以直接扩展系统的业务处理能力,而不需要额外的代价。
引入消息中间件后,竣工处理模式变化如下所示:
改造后竣工消息处理模式示意图
此次在竣工环节引入消息中间件后,按照订单类型、订单处理要求分别建立了不同的生产者和消费者。在订单处理过程中,由于生产者和消费者相互不干扰,且可以随时根据消费者处理的情况增加消费者,从而提升订单处理效率。数据显示,订单处理效率相比优化前提升了 6-8 倍!
优化展示数据对比:
优化前后系统处理性能对比
在原有部署架构模式下引入消息组件,不需要增加额外的服务器,只需要将消息组件部署在原来的服务器上,配置生产者和消费者模式后,即可快支撑现网业务。引入消息组件后的运维模式也不需要发生太大变化,竣工队列的监控和异常处理均可沿用原有的维护处理界面,实现运维的无缝衔接。
搜索引擎引入
BSS3.0 热点数据加载主要涉及到字典数据查询、热销排行、热搜词、搜索缓存、查询套餐及销售包、选套餐等业务活动。传统的检索方式,大部分都会使用到像 like 这种的 SQL 语句,高级一些可能是先分词,后通过分词 index 相关的记录,弊端是 SQL 语句的性能与全表扫描机制导致了非常严重的性能问题。
针对搜索引擎 ElasticSearch 的使用,我们在引入前先做了前期调研,输出可行性分析报告。发现对于现在的业务模式,在套餐选购环节,引入 ES 会有以下好处:
1)热点数据均匀分布:引入 ElasticSearch 对于热点数据能够存储到各个数据节点上,数据能够更加分散管理;
2)搜索快捷:通过 ES 对销售品进行搜索,效率会更高;
3)Restful API 交互方式:对程序员非常友好,学习成本更低,不需要写额外代码、繁琐逻辑,掌握某种语言 sdk,通过简单通用的 http 请求就能实现对 index、type、docuemet 管理。
但是,在现有产品上引入 ES,我们面临了几个关键问题需要考虑和解决:
01 数据结构设计
ES 和大多数 NoSQL 数据库类似,是扁平化的。而系统原有的底层查询逻辑依然依赖于 MYSQL 的表模型,如何缩小扁平化和目前系统的关系模型差异是亟需解决的一个问题。
依照现有的销售品搜索和展示模式,我们必须要考虑将套餐关联查询的业务逻辑进行分离。如销售品、销售品限制、销售品包含对象、对象标签关系、标签规格,以销售品标识为索引合并到一个文档中,文档建模时让每个文档都包含所需的所有信息,突破关系型数据库设计的思维定式,将业务转化为没有关联关系的文档形式。套餐检索时对检索条件进行逻辑处理及组装,最终直接匹配查询。
02 存量数据同步
为保证引入 ES 后能够快速承接生产应用,如何将存量数据一次性同步到 ES 中,并且保证数据的一致性?
将销售品相关数据存量同步到 ES 类似一次数据割接,同步的方式有很多,针对业界使用较多的插件选型,我们采用了 logstash-input-jdbc。logstash 通过 sql 语句分区间对数据进行查询,然后输出到 es 进行实现。由于一个 logstash 实例可以借助 pipelines 机制同步多个表,也可以配置关联查询,我们将需要同步到宽表的数据,按宽表查询逻辑制定对应的查询 sql 进行全量同步。
03 增量数据的同步
销售品的上下架和修改操作都是由产销品配置中心发起,对于上下架的销售品,如何快速及时地进行同步,不产生延时?
解决措施如下:
1、产销品配置中心一条业务数据落库落表,通过 MQ 将数据同步给受理中心;
2、受理中心异步把该条数据发送到 ES;
3、ES 把该条记录按照事先写入的规则、配置放入自己的索引库中;
4、受理查询的时候,由受理中心服务端把这个请求先发送到 ES,得到数据后,根据需求进行拼装、组合数据,返回给客户端。
优化后例如销售品模糊搜索、套餐列表展示等热点数据加载查询速度快了一倍之多。
配置中心引入
由于产品功能的复杂性,目前控制各种功能的开关和系统类参数都散落在系统各个地方,大部分是通过表及代码的配置文件配置实现,这种方式处理存在几个问题:
查找困难:系统运维人员或者开发人员查找参数或者开关数据,需要翻看代码或者查找数据库才能完成;
维护困难:修改某个参数或者开关数据,需要版本发布或者刷缓存,不能实时生效。
为解决上述两个难题,我们通过引入配置中心,提供界面化配置能力,实现系统开关及配置参数等可视化管理能力和参数修改后实时生效功能。但是在引入配置中心时,系统也需要进行如下的改造和优化:
1)对所有开关进行统一编码,确定编码规范。如开关编码格式规范化、开关编码静态文件规范化、代码中所有写死开关名称处,修改为引用静态变量;
2)引入配置中心服务作为开关配置来源,通过配置修改开关的状态等参数。
配置中心开关文件设置
核心包、产品包所有开关统一配置在一个标准化文件中,配置内容为:开关描述、开关名称、开关状态(后期新增开关,配置值应为 T/F 或空)。
配置中心开关配置界面
引入依赖文件
添加需要注入的开关文件
定义与文件对应的对象,包括 get 方法
通过注解的方式获取配置中心配置
提供静态反射方法获取开关的值
3)规范工具类路径,提供统一的判断、查询 API
提供开关是否打开 API
提供开关是否打开 API
提供直接获取开关状态 API:由于系统存量开关配置并不是 T/F,而是 true/false、0/1 或 Y/N,提供该方法直接取出字符串,在代码中进行对比(后期新增开关,应尽量定义为 T/F,便于使用工具类判断)
4)开关查询界面使用
支持根据开关编码、描述等查询开关,查询后界面展示编码、描述以及开关状态;点击编辑,可修改开关状态、开关描述,编码不可修改;支持新增、删除开关。
配置中心配置参数界面
小结
系统架构在于面对业务场景给出优雅的解决方案,使得系统在业务快速变化的情况下,仍然能够实现快速迭代和健康运营,最终达到降本增效的目标。
BSS3.0 系统架构优化并不是从零开始去构建,而是在现有的产品上不断优化,添砖加瓦。我们通过对产品能力集约化,引入开源的中间件等方式,对系统进行不断地打磨和提升,既保证服务的更新不会影响客户端,又使架构变得更合理、更灵活、具备更高可用性以及能够快速适应业务变化。产品架构的优化调整,也使我们在后续业务、运维提升方面的工作变得更加游刃有余。
版权声明: 本文为 InfoQ 作者【鲸品堂】的原创文章。
原文链接:【http://xie.infoq.cn/article/f62bf5f22e45599060d29253f】。文章转载请联系作者。
评论