写点什么

浅谈 BSS3.0 产品“守成”之策下 • 运维提升篇

用户头像
鲸品堂
关注
发布于: 2021 年 04 月 25 日
浅谈BSS3.0产品“守成”之策下 • 运维提升篇

从软件生命周期的角度看,软件开发阶段只占整个生命周期的 20%~30%左右,软件运行维护阶段却是一个长期的过程。


因此如何让漫长阶段的事情变得更为简单高效,在 BSS3.0 的运维提升之路上,我们又做了什么呢?


缓存优化


缓存的本质是加速访问,访问的数据要么是应用中心的数据库——让数据离用户更近;要么是之前的计算结果——避免重复计算。缓存需要用空间换时间,在缓存空间有限的情况下,需要优秀的置换换算来保证缓存有较高的命中率。而缓存需要先将数据刷新到缓存中,在刷新过程中会存在刷新数据不及时等问题;并且在缓存中的数据,对运维和开发人员来说,都是黑盒,无法让人清晰地了解缓存中的数据是否已经存在,抑或数据是否与数据库的数据一致等。


改造前


改造后


在解决缓存刷新问题时,优化方案主要是利用了 Zookeeper 的特点:在 zk 上面创建一个节点。当该节点下的子节点发生变化时,可以使用 Zookeeper 提供的 api 做一个实时的监听。Zookeeper 提供的 TreeCache 有以下 3 个特点:


1)永久监听指定节点下的节点的变化。2)可以监听到指定节点下所有节点的变化,比如说指定节点“/example”, 在下面添加“node1”可以监听到,但是添加“node1/n1”也能被监听到。3)可以监听到的事件:节点创建、节点数据的变化、节点删除等。


方案原理步骤如下:


1)项目启动时运行 static 静态块,创建一个监听 zk 下某给定结点变动的监听器 TreeCacheListener。

2)第二步与改造前一样,点击刷新按钮时通过门户调用到受理中心。

3)不同的是,改造后不用再去获取接口服务类的提供者循环往分布式缓存上写命令,将命令序列化之类,而是写到 zk 的节点上去。

4)此时凡是连接了同一 zk 集群的所有的机器实例。都会监听到 zk 上面该节点的变化。并且可以获取到节点下之前写入的命令。获取命令后,在反序列化获取接口名,方法名以及入参等信息。根据这些信息就可以调用本地刷新缓存的方法了。本次缓存优化使刷新缓存会变得更加实时,并且不会存在缓存数据漏刷的情况。

5)此外,对缓存刷新还增加了可视化界面,便于维护人员实时查看缓存中的数据,提供按详情节点、表单字段,服务 ip 和端口节点数据的查看,对与数据库不一致的数据可以清晰直观的观测到,排查问题更加迅速便捷。


缓存数据可视化界面


日志编码规范化


BSS3.0 当前各线上系统运行时,受理过程中会出现一些运行报错。主要表现在营业员办理业务过程中,特别在办理复杂业务的时候出现各种系统报错。


日志编码规范化的改造通过规范异常处理,使用 ZCM 捕获各种系统异常,如系统运行时报错、业务规则提示、sql 执行报错等并进行统计,并对异常根据不同维度对业务逻辑性合理性、规则设计的合理性、sql 部分问题等进行分析,以提高代码的健壮性和代码整体质量,同时也有助于运维支撑人员能够快速判断故障信息。


改造过程中,我们统一了日志规范,对日志级别、模块编码、异常编码、错误编码与关键信息进行了重定义与划分。具体规范举措如下:


日志级别定义:


DEBUG:系统开发调试中出现的信息。

NORMAL:运行中出现需要记录的正常业务处理信息;测试、维护人员,根据 normal 日志能够掌握业务运行的关键信息。

WARNING:运行中出现的异常信息,当前业务可以继续运行。

ERROR:运行中出现异常信息,当前业务无法继续运行,但下一笔业务可以继续运行。

FATAL:系统无法正常运行,日志打印完后,程序退出。

INFO:信息点、在线跟踪、函数性能日志使用。


异常编码定义:


统一异常编码 9 位:对象类别编码(1 位)+ 所属中心编码(2 位)+ 异常类别编码(1 位)+ 子模块编码(2 位)+ 错误编码(3 位)


1、统一模块编码(对象类别编码与所属中心编码同模块编码定义):

1)统一模块编码 3 位:对象类别编码(1 位)+ 所属中心编码(2 位)。

2)所属对象类别统一为应用软件类,编码为 4。

3)中心编码:

例如,受理中心的模块编码为:402;基础运营的模块编码为:401。


2、异常类别编码:


3、子模块编码为各个中心自定义子模块编码:

ZCM 将根据中心编码和子模块编码定界异常所属中心的具体模块进行统计,并对异常进行分析,各个中心各个子模块也能从 ZCM 获取到对应子模块的异常情况。


4、错误编码为各种业务异常场景的自定义编码:

在异常编码中,后三位为具体的异常错误码,建议统一常见的异常编码,并统一定义对应的关键描述信息。


与此同时,代码改造我们还设置了整改范围,定义异常处理工具类。最终通过 ZCM 进行异常日志统计分析。


确立整改范围:

核心层、产品层、定制层需要整改以下异常:

1、SQL 类异常捕获,并按规范转换异常编码信息以及异常信息;

2、系统类异常不会,并按规范转换异常编码信息以及异常信息;

3、代码逻辑主动抛出自定义异常需要按规范输出编码信息以及异常信息;

4、错误日志打印需要按规范输出编码信息以及异常信息。


异常处理工具定义:


为了规范异常日志打印、异常编码使用,并满足国际化异常日志打印的需要,各个中心统一按照规范封装异常处理工具,所有业务异常日志打印均使用异常处理工具处理。

1、核心、产品、定制分别各自作工具定义封装;

2、工具实现异常枚举定义、错误码定义(按照第 2 章节规范定义)、错误关键信息定义;

3、工具实现错误日志打印统一接口;

4、工具实现自定义异常转换统一接口。


统计结果展示:

ZCM 通过配置日志统计分析规则,对结果查询操作分析如下:

1、过滤条件: 可以根据中心、异常类型、子模块过滤异常错误日志的统计情况;

2、操作->详情:展示该统计到的异常错误日志的日志、调用链收集;

3、维修人员可以关注系统目前业务运行发生的异常情况,及时根据对应的日志以及调用链排查潜在的的业务问题。

日志异常统计分析界面


日志埋点


埋点就是在应用中特定的流程收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑。例如在受理过程经历了哪些流程,是通过埋点获取到基础的数据。


埋点以监控用户行为居多,但是在受理场景中不仅仅是为了监控用户的行为,还要为运维人员提炼有用的数据做为系统优化分析的依据。重点不在于埋点的作用,而是在于获取埋点数据后的对变化数据进行分析,定位出实例信息经过了哪些流程,在哪个环节存在问题。


当我们通过系统的工具或者目前的手段只能知道入参和出参,对内部调用一无所知的时候;计算结果是对的,过程是错的,这也会一种隐患。这个时候我们引入业务埋点的手段,将过程数据进行监控采样,在问题的分析过程中提供有效依据。


为了不影响主线程的效率,我们通过异步采样的方式将碎片收集;触发另一个线程进行计算,将计算结果存入缓存中。


埋点改造示意图


如上图所示,我们将业务中的实例变动和关系变动做了监控埋点。当受理整个链路过程中存在实例变动、关系变动时,manage 层(实例对象缓存管理工程)缓存的变化触发埋点采集逻辑,埋点业务逻辑将实例数据、关系数据变化的新旧值转换成 ES 实体,再通过异步计算,将变化的实体对象存入业务链的 VO 对象中,并且建立好索引,最终存入 ES 宽表之中。当业务受理过程中,出现无法复现的业务受理故障,通过可视化管理页面,研发人员或者运维人员可以直接在界面上进行搜索、查看日志数据信息。从而可以轻松地执行高级数据分析,并且以各种图标、表格和地图的形式分析可视化数据。


中心间服务流量监控


在省份系统运营过程中,部分应用会采用爬虫方式来系统爬取一些数据,为保障这部分应用在合理范围使用爬虫技术来获取系统数据,我们需要针对部分服务进行流量监控,当某些服务流量超过阈值时,需要限制服务调用。为解决该需求,我们提供一套服务流量监控和管理方案。


具体改造点:


(1)引入 Sentinel 流量监控组件

根据行业成熟的组件比较,最后选择 Sentinel 开源组件,该组件除了有丰富的应用场景外,还有完备的实时监控、开源生态和丰富的 SPI 扩展点等特性。

(2)配置了流量监控的开关

通过配置基于数据库的动态开关,实现对流量监控的开启和关闭。在需要的时候可动态开启,在不需要时可以动态关闭,在满足业务需求的同时,可进一步的节省系统资源。

(4)实现了基于 zookeeper 的自管理、高可用的集群限流

利用 zookeeper 的相关特性,实现以下两个功能点,将原来需要手动在控制台进行集群组成改造为启动自动组建集群,并且实现自动高可用管理,与 Dasboard 完全解耦,便于在生产环境使用集群限流。

(5)实现 Dashboard 的自动连接

利用 zookeeper 的相关特性,实现 dashborad 的动态连接,将原来需要的编码配置变为动态配置,进一步减少对 CI/CD 和部署环境的侵入性。

(6)使用 ZooKeeper 配置规则, 实现“推模式”的动态规则策略

规则不应该保存内存中,应该持久化到动态配置中心,而应用直接从配置中心订阅规则。这样,Dashboard 和应用就通过配置中心实现解耦了,这是典型的生产者消费者模式。通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更。

(7)对 Sentinel Dashboard 源码进行改造,让其支持下发应用维度的集群限流规则

基于 zookeeper 实现规则的集群动态配置和分发。

(8)可通过实现 Sentinel-Param-Getter 接口,定制热点参数

热点参数限流可以防止热点数据占用并消耗过多的系统资源,导致对其他数据的请求处理受到严重影响。


结语


产品架构的先进性和性能的优越性是用户体验的基石,产品提升的最终目标是优化用户的感知与体验,俗话说:“天下武功,唯快不破”,这句话放到产品优化上也是适用的。


我们做产品的提升与优化都是为了追求产品的“快”。而优化的过程则需要我们做好打持久战的准备,既不能过早优化,也不能过度优化。最好的方式是深入理解业务知识,了解系统瓶颈所在,建立精细化的监控平台。当系统出现问题时,我们就可以做到有条不紊,从应用、架构、运维等层面进行优化分析,设定一系列期望的性能指标,并对每次优化措施和效果进行总结思考,从而形成自己的方法论。如今产品的提升和优化工作,不再是一锤子买卖,在上线之后还需要持续的开发与维护,大量用户的涌入也会带来性能问题。因此需要自动化的检测性能问题,保持稳定的测试环境,持续的发现并解决性能问题,而不是被动地等到用户的投诉。


世间万物唯一不变的就是变化,客户需求一直在变,我们的系统应用也将被动或者主动地发生变化。当变化来临的时候,如何设计出易于扩展、自动适应客户需求变化的软件架构;如何编写更高效、更高质量的代码,是软件工程师一门永恒的课题。在这门课程的探索中,需要我们不停积累业务知识,扩展知识面,发散思维,甄别技术未来演进趋势。在产品研发、优化和提升的道路上,我们会坚定并坚持地走下去!

发布于: 2021 年 04 月 25 日阅读数: 16
用户头像

鲸品堂

关注

全球领先的数字化转型专家 2021.03.16 加入

鲸品堂专栏,一方面将浩鲸精品产品背后的领先技术,进行总结沉淀,内外传播,用产品和技术助力通信行业的发展;另一方面发表浩鲸专家观点,品读行业、品读市场、品读趋势,脑力激荡,用远见和创新推动通信行业变革。

评论

发布
暂无评论
浅谈BSS3.0产品“守成”之策下 • 运维提升篇