写点什么

统一运营平台架构设计

  • 2020-03-22
  • 本文字数:3050 字

    阅读完需:约 10 分钟

统一运营平台架构设计

1 项目背景

为了配合 APP 大改版,旧的 APP 后台服务系统因多年维护与需求迭代变更,造成维护成本越来越高,且不能满足新版 APP 的很多功能。因此,决定启动乐高系统来承载新版 APP 的所有需求。时间很紧迫,任务也非常重。经过思考后,就有了第一次小组会议的初步架构设想图:


2 项目分析

作为 APP 后台的管理系统,主要就是操作 APP 每个原生页面的具体数据结构。要求各种数据动态配置,各种属性随意修改,在不进行版本升级的前提下,即时生效。简言之,也就是项目负责 APP 页面数据的下发,内容动态配置管理。


为了应对内容数据的可随意更改,可随时生效这个需求,我们觉得 Spring Express Language(后面统一称为 SpEL/EL)特别适合这个业务场景。所以,在系统里大量应用在页面数据调用接口动态取数据所需配置的地方,也成了整套系统的核心价值所在。如下图为 SpEL 在乐高平台的应用形式:



以及对于此类内容输出系统的特点分析如下:


3 架构设计思考

通过上述特点分析,可以知道这是一个典型的重读操作的系统,因此项目分成了两部分:


  • 一个后台管理负责配置基础页面数据,也就是模板的配置信息。

  • 一个负责响应 APP 的接口请求返回页面结构数据,也就是动态渲染 APP 所需要的真实数据结构和内容,包含千变万化的规则需求和运营逻辑。


而新项目需要新的框架去实现,我们拒绝墨守成规,希望适度的引用新技术去驱动业务的发展。因此,选型最新的 Spring Boot2 与 JDK8 配合。Spring Boot2 是基于 Spring5 上集成而来的,Spring5 是目前非常优秀且最新的 Java 应用框架,这个大版本增加了很多新的特性。比如:


  • JDK 基线更新

  • 核心框架修正

  • 核心容器更新

  • 含 Kotlin 在内的函数式编程

  • 响应式编程模型(重点)

  • 测试改进

  • 库支持

  • 中止支持


而 JDK8 的 Stream,Lambda 表达式等特性的应用,也成了系统开发过程中的常见姿势。具体详细架构如图:



页面数据渲染流程:



请求流:



整套系统有如下优化处理:


  1. 整个应对 APP 访问的页面数据渲染系统,不依赖于 MySQL 数据源,所有页面基础数据均读 Redis 缓存数据。

  2. 可封装或不封装业务接口,根据业务场景复杂度而定,一切以页面配置简易化为主。所有需要动态配置数据结构的模板元素配置项,都用 EL 表达式来代替。当然虽然这个方式大大提高了动态灵活性,但加大了运维人员的门槛高度,所以,第一版上线的所有表达式配置项,由研发配置。

  3. 业务接口熔断处理,基于 Hystrix 的熔断器与方法降级处理,做页面请求接口托底方案。另一个托底方案,是运营可以配置多个相同页面模板,根据用 EL 表达式描述的显示规则来做模板托底方案。

  4. 为了提升系统性能,主要做了如下几点优化处理:


  • 页面全局接口基于正则匹配的表达式抽取,相同方法参数统一请求处理,将请求结果保存在 Spring EL 渲染模板的上下文中作为结果变量,将原先配置的表达式替换为从结果变量中提取结果数据。这样就可做到:一个接口相同的方法,只要参数一致,无论在页面中配置了多少处表达式,在单次渲染整个页面周期时,只做一次调用。大大提升了性能,降低了延迟。

  • 异步结果请求。上面所有需要调用接口取数据的表达式,均被分配到了单独一个线程去请求结果,其实保存在上下文中的环境变量就是封装结果的 Future。页面渲染时,会先分配 N 个线程去请求数据,等到后续真正组装结果时,才会去调用 get 阻塞获取结果。当然这样做,提升速度的代价就是极大消耗 CPU 性能,因为线程池需要设置的比较大,而具体设置为多大,还要在不断试验的基础上不断优化调整,以达到服务器最优效能和最大并发支持。

  • 基于 Actor 模型 Reactor 响应式处理页面数据。页面数据是有规则的,也就是多个模板集合组合起来的,而每个模板里又是一个元素集合,每个元素里又是一个属性集合,是个比较规范的数据结构,虽然最大的坑在于层级深度不固定,但是已经用 JSON 去填了这个坑。而针对这个相对规范的数据层级结构,用响应式编程(流式处理)再合适不过了。So,基于 Flux 使用和 Subscriber 的大量使用不再赘述。

  • 数据读取走本机缓存。因为从 Redis 读取速度还不到极致,虽然不读 MySQL,但是每次构建页面数据,读多次 Redis 的网络开销,也是不想耗费的。所以,首要考虑的还是本机内存级缓存的实现。因此,基于 Guava 的 LoadingCache 构建本地缓存方案就集成进来了,当然效果也是非常显著的,但是本地缓存方案并不能长久支撑下去,对于后续支撑业务线的增长,能够支撑超过内存容量的缓存方案还是要考虑进来的!不排除后续随着业务的增长,缓存数据的急剧增长,增加本地硬盘数据缓存以及 ElasticSearch 等支撑系统。

  • 规则链式执行。因规则的多样性,一个页面每个模板甚至于每个元素都是可以去配置各式各样的规则的。比如 A|BTest,坑位优先级,分流,随机等等规则均可以应用在任何模板或元素组上。为了高效执行配置的所有规则逻辑,执行规则前,将规则集创建成规则链。以模板为粒度,以第一个规则执行为起点,执行结束后,判断有无下游规则。进而每个模板被传递给下游规则去执行相应规则逻辑。基于 Reactor 的 Flux 原理图:



至于为什么会选型 Reactor,主要还是基于业务场景的综合考量,对于『多模板->多元素』数据结构渲染很符合流式编程引擎的适用场景。页面规则执行的切入点,分为准备数据和调整数据,如图所示:


4 项目开发中的问题

项目的研发进度还是很快的,这源于团队的高效工作与优秀的执行力。但由于时间紧迫,各业务方提供的接口也参差不齐,返回结构也形态各异。这也是没有一上来就做接口规范所挖的坑。


  • 因此有一个很大的工作量就是重新封装各业务方接口,包装成自己所负责页面方面用表达式 SpEL 描述的样子。而这些工作的确是可以通过事先规范好接口返回标准来避免的。

  • 其次有个很大的工作量就是 SpEL 表达式在各业务页上面的配置,因为需要验证表达式正确性,需要到预发环境验证,因为没有测试环境,对工作效率造成了很大的影响。后来,为了应对这个 SpEL 验证表达式正确与否的问题,专门开发了一个测试接口,才一定程度上解决了这个问题。

  • 最后一个对团队比较有挑战的是管理端 UI 的开发。整个团队是纯后台开发团队,对于前端开发经验较少,为了让全体成员快速进阶全栈工程师,大家也是恶补了以 VUE,ElementUI 为基础的前端基础开发知识。目前系统配置效果如下:


5 回归分析

为了应对需求的动态可配置,采取了页面配置里各种 SpEL 表达式;但造成最大的一个问题就是——运营体验不佳!


  • “这都是啥呀?完全看不懂!”

  • “稍微一改,页面就崩了”

  • “完全不敢动啊,一动就坏!”


各式各样的的吐槽声接憧而至,表现了运营对系统易用性的各种不满。的确,表达式就是代码,看不懂而且稍微改动一个标点符号的确就会造成异常!用户是上帝,如何满足易用性的需求呢!因此进行了一些优化:


  • 表达式配置改为用户选择方法,让 SpEL 表达式在用户看不到的地方动态生成。(这点已基本实现,先配置在系统专门维护的方法表里,然后供页面选择)

  • 尽量剥离系统中业务接口的直接引用,保持系统轻量化。采用 RPC 框架的泛华调用方式,避免 jar 包引入方式。


6 未来规划

关于乐高 2.0 的未来规划,一方面期望以提供平台型页面运营数据输出服务为基础,可视化配置体验以及完整活动页面输出能力。另一方面,拓展支持范畴,例如正在规划和进行的活动支持系统(暂未命名),作为乐高系统群或乐高运营支撑生态的重要一部分也在积极规划调研与实现中。



最后,乐高平台目前仍在积极的接入各部门的页面搭建需求,并提供稳定高效的服务。在欢迎大家接入乐高平台的同时,我们将积极接受来自四面八方的批评与建议,希望稳固迭代,支撑起大家对页面搭建的需求与重任。


2020-03-22 21:053301

评论

发布
暂无评论
发现更多内容

【Java 基础你一定要掌握的知识点】Java异常处理和设计

猫的树

Java 异常处理

Taro2/3做小程序开发的使用心得和方法

9527

小程序 taro

洞察数字化转型现状及未来 《中国金融机构数字化转型》白皮书发布

科技热闻

三证加持,澳鹏中国又获ISO9001及27701认证

澳鹏Appen

隐私保护 ISO 数据安全 质量检测

【云计算】企业上云后需要避免的几个错误

行云管家

云计算 企业上云 堡垒机

小程序在产业互联网中的作用

Geek_99967b

小程序

Apache Flink ML 2.1.0 发布公告

Apache Flink

机器学习 大数据 flink 流计算 实时计算

龙蜥下游发行版 Alinux 和 UOS 成为 OpenSCAP 官方首批支持的国内 OS

OpenAnolis小助手

国产 龙蜥操作系统 UOS v20 OpenSCAP Alinux 2/3

无声的AI:昇腾AI如何用大模型破解手语学习的难题?

脑极体

LeetCode-118. 杨辉三角I(java)

bug菌

Leet Code 7月月更

Go 原生插件使用问题全解析

SOFAStack

Go 语言 开源软件 MOSN 问题解析 开源学习

数据分析引擎百花齐放,为什么要大力投入ClickHouse?

字节跳动数据平台

let、var、const 的区别

7月月更

使用百度开发者工具 4.0 搭建专属的小程序 IDE

百度Geek说

ide 开发者工具

千亿IT运维市场,来到凭「效果」说话的时代

ToB行业头条

nacos注册中心之客户端服务注册

急需上岸的小谢

7月月更

leetcode 135. Candy 分发糖果(困难)

okokabcd

LeetCode 贪心算法 算法与数据结构

【C语言】进阶指针six

謓泽

7月月更

《看完就懂系列》答应我,看完就开始用Symbol好吗?

南极一块修炼千年的大冰块

7月月更

低代码如何构建支持OAuth2.0的后端Web API

葡萄城技术团队

后端 低代码 Oauth

java零基础入门-继承

喵手

Java 7月月更

高效实战|航空业海量日志数据的智能化分析

云智慧AIOps社区

运维 数据分析 日志分析 日志管理 运维技术

公众号关联【排队助手】小程序

天天预约

小程序 工具 SaaS设计 排队

【Java 实战】实现大转盘抽奖

猫的树

Java 大转盘抽奖

开源仓库贡献 —— 提交 PR

攻城狮杰森

git GitHub PR 开源贡献 7月月更

TCP/IP协议常见漏洞类型

郑州埃文科技

TCP/IP 漏洞 IP地址

直播带货源代码——直播带货系统

开源直播系统源码

直播带货源码 直播带货系统 开源源码

金融有底,赋实有数!《中国金融机构数字化转型》白皮书重磅发布

科技热闻

新版网络安全等级保护测评报告模板包含哪些内容?哪里可以找到?

行云管家

等保 等保测评 等保测评报告

统一运营平台架构设计_文化 & 方法_京东数字科技产业AI中心_InfoQ精选文章