“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

统一运营平台架构设计

  • 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:052866

评论

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

模块一作业

上善

如何高效便捷的画出炫酷神经网络图

不脱发的程序猿

人工智能 神经网络图工具 神经网络可视化

架构师实战营 模块八总结

代廉洁

架构实战营

查找——HASH

若尘

数据结构 hash

Spring源码解析 -- SpringWeb请求映射Map初始化

Java spring 源码解析

币安链智能合约Dapp系统开发方案

薇電13242772558

智能合约

Dlx Coin手机挖矿系统软件开发公司

Yuumi悠米挖矿APP系统开发模板

完了,又火一个项目

程序员鱼皮

JavaScript GitHub Vue 大前端 React

淘筱优软件开发|淘筱优APP系统开发

bzb矿机软件系统开发

🏆「作者推荐」【JVM 性能分析】精心准备了一套 JVM 分析工具的锦囊(中部)

洛神灬殇

JVM 性能分析 7月日更

hive 与传统数据库对比

五分钟学大数据

hive 7月日更

架构师实战营 模块八作业(设计消息队列存储消息数据的MySQL表格)

代廉洁

架构实战营

BJIA数字星座乐园软件系统开发模板

趣玩吧EVO软件系统开发方案

小牛XNT挖矿APP系统开发

FIL分币系统源码开发App

获客I3O6O643Z97

IPFS怎么挖矿 ipfs有什么用 质押挖矿 fil币

iOS开发 · 一套iOS底层试卷-我想和你分享

iOSer

ios 面试 iOS底层 iOS 知识体系

XDD手机挖矿系统开发资料

Go 语言中一些不太常见的优化

Xargin

性能优化 后端 Go 语言

Ubuntu Server 20.04搭建kafka集群

玏佾

kafka kafka配置 kafka数据 Ubuntu20.04

TP钱包Defi挖矿系统开发【专业定制】

获客I3O6O643Z97

区块链 DeFi质押挖矿 质押挖矿

学点项目管理,对咱程序员很重要~

后台技术汇

项目管理 项目管理工具

FIL币挖矿合法吗?FIL挖矿会叫停吗?

Uranus天王星系统软件开发介绍

Python+OpenCV创建级联文件(Windows7/10环境)

不脱发的程序猿

Python OpenCV 目标对象识别 OpenCV创建级联文件

果果世界APP系统开发内容

你有多少密码是123456

MySQL从删库到跑路

密码管理

yarn 的基本介绍和产生背景

大数据技术指南

YARN 7月日更

第八课作业

杰语

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