内容简介:2018年金融组织结构大调整,新的组织结构是中台研发。期初我对这个名称也感觉新鲜,了解后就发现,是连接前端部门与各业务部门桥接与提供公共服务的部门。新组织架构调整伊始,开始对接各种项目,最繁琐的或许就是重前端的活动页搭建项目,也许因为这个原因吧,领导把我安排到了接收这个项目的“营销与权益”组。接手别人的项目总是痛苦的,以至于最后我们打算自己做一套。虽然很复杂,但是慢慢来应该不成问题。所以我决定全新用Spring boot2+,管理界面界面采用ElementUI做SPA,搭了一套还算比较完整的项目。总觉得以
项目背景&前期铺垫
2018年金融组织结构大调整,新的组织结构是中台研发。期初我对这个名称也感觉新鲜,了解后就发现,是连接前端部门与各业务部门桥接与提供公共服务的部门。
新组织架构调整伊始,开始对接各种项目,最繁琐的或许就是重前端的活动页搭建项目,也许因为这个原因吧,领导把我安排到了接收这个项目的“营销与权益”组。接手别人的项目总是痛苦的,以至于最后我们打算自己做一套。虽然很复杂,但是慢慢来应该不成问题。所以我决定全新用Spring boot2+,管理界面界面采用ElementUI做SPA,搭了一套还算比较完整的项目。总觉得以往的项目还是太过于陈旧,新项目就全部用最新的技术和框架重新搭建。小组成员们边了解需求边尝试,用了几周的时间做好了基础版的拖拽生成页面的Demo。当然没有专业前端的加入,界面还是比较丑陋的。
突然降临的挑战
上层领导决定公司APP大改版,时间很紧迫,任务非常重。原先交接过来的系统不能够支持新版APP的页面数据结构。虽然时间非常紧迫,从接到任务到上线预计也就一个月的时间,但考虑的需求比较简单还是决定全部重新做(后来发现,先期了解的需求并不全面,真是把自己给坑了)!有了上面“活动搭建”项目的后台,新项目进展还是比较迅速的。经过了解需求,思考了一下午,我大致想做一套基于领域模型驱动的架构(虽然由于自己才疏学浅,并没有在项目中把领域模型驱动设计发挥出来,但初衷还是有的),也就有了第一次小组会议我在墙上画下的初步架构设想图如图1:
当然我想表达的是这样子的:
项目分析
作为APP后台的管理系统,主要就是操作APP每个原生页面的具体数据结构。要求各种数据动态配置,各种属性随意修改,APP在不进行版本升级的前提下,即时生效。简言之,也就是项目负责APP页面数据的下发,内容动态配置管理。而为了应对内容数据的可随意更改,可随时生效这个需求,我觉得Spring Express Language(后面统一称为SpEL)特别适合这个业务场景。所以,在系统里大量应用在页面数据调用接口动态取数据所需配置的地方,也成了整套系统的核心价值所在。
架构思考
这是一个典型的重读操作的系统,所以我就把项目分成了上面的两部分,一个后台管理,一个负责响应APP的接口请求返回页面结构数据。
因为Spring Boot2+是基于Spring5上集成而来的,Spring5是目前非常优秀且最新的 Java 应用框架,这个大版本增加了很多新的特性。比如:
- JDK 基线更新
- 核心框架修正
- 核心容器更新
- 含 Kotlin 在内的函数式编程
- 响应式编程模型(重点)
- 测试改进
- 库支持
- 中止支持
而基于Spring5上构建全新的系统,肯定会事半功倍的。具体详细架构如图
整套系统有如下几个特点:
- 整个应对APP访问的CMS系统,不依赖于 MySQL 数据源,所有页面基础数据均读 Redis 缓存数据。
- 可封装或不封装业务接口,根绝业务场景复杂度而定。一切以页面配置简易化为主。所有所需要动态配置数据结构的模板元素配置项,都用EL表达式来代替。当然这个方式大大提高了动态灵活性,但是加大了运维人员的门槛高度,所以,目前为止,第一版上线的所有表达式配置项,均有我们研发自己配上去的。
- 业务接口熔断处理,基于Hystrix的熔断器与方法降级处理,做页面请求接口托底方案。另一个托底方案,是运营可以配置多个相同页面模板,根据用EL表达式描述的显示规则来做模板托底方案。
- 为了提升系统性能,主要做了如下几点优化处理:
- 页面全局接口抽取,相同方法参数统一请求处理,将请求结果保存在Spring EL渲染模板的上下文中作为结果变量,将原先配置的表达式替换为从结果变量中提取结果数据。这样就可做到:一个接口相同的方法,只要参数一致,无论你在页面中配置了多少处表达式,在单次渲染整个页面周期时,只做一次调用。大大提升了性能,降低了延迟。
- 异步结果请求。上面所有需要调用接口取数据的表达式,均被分配到了单独一个线程去请求结果,其实保存在上下文中的环境变量就是封装结果的Future。页面渲染时,会先分配N个线程去请求数据,等到后续真正组装结果时,才会去调用get阻塞获取结果。当然这样做,提升速度的代价就是极大消耗CPU性能,因为线程池需要设置的比较大,而具体设置为多大,还要在不断试验的基础上不断优化调整,以达到服务器最优效能和最大并发支持。
- 基于Actor模型Reactor响应式处理页面数据。页面数据是有规则的,也就是多个模板集合而组合起来的,而每个模板里又是一个元素集合,每个元素里又是一个属性集合,是个比较规范的数据结构,虽然最大的坑在于层级深度不固定,但是已经用JSON去填了这个坑。而针对这个相对规范的数据层级结构,用响应式编程(流式处理)再合适不过了。So,一堆Flux使用和Subscriber飘过…
- 数据读取走JVM。速度还不到极致,虽然不读MySQL,但是每次构建页面数据,读多次Redis的网络开销,我也是不想耗费的。So,基于Guava的LoadingCache构建Jvm本地缓存方案就在优化系统的路上走马上任了!至于有人问为什么不基于HashMap的本地静态变量做?仅仅是为了实现的更加优雅!当然用HashMap也是完全可以做的,只是我却是一定程度上喜欢用牛刀。
项目开发
项目的研发进度还是很快的,由于时间紧迫,各业务方提供的接口参差不齐,千奇百怪。这也是我们没有上来就做接口规范所挖的坑。
- 我们有一个很大的工作量就是重新封装各业务方接口,包装成自己所负责页面方面用表达式SpEL描述的样子。而这些工作的确本不该有我们部门的研发去做的。
- 其次有个很大的工作量就是SpEL表达式在各业务页上面的配置,原本我以为这是最简单快捷的工作。但是由于其他成员没有了解过,导致出错不断。再就是验证表达式正确性,需要到预发环境验证,因为没有测试环境,对工作效率造成了很大的影响。后来,为了应对这个SpEL验证表达式正确与否的问题,专门开发了一个测试接口,才一定程度上解决了这个问题。其实这个验证接口确实该早些准备好的,的确是我的失职。
回归分析
为了应对需求的动态可配置,采取了页面配置里各种SpEL表达式。造成最大的一个问题就是,运营不爽了!
– “这都是啥呀?完全看不懂!”
– “稍微一改,页面就崩了”
– “完全不敢动啊,一动就坏!”
各式各样的的吐槽声接憧而至。表现了运营对我们系统易用性的各种不满,我也是一脸无奈。的确,表达式就是代码,把最抽象的东西摆在他们眼前,看不懂都是次要的,他们稍微改动一个标点符号的确就会造成异常!
可是,他们是用户,无论如何得满足啊!为此,我也时常反思,系统还能怎么优化?如果再让我重新实现一遍呢?
对此列举系统优化点:
- 表达式配置,改为用户选择方法,让SpEL表达式在用户看不到的地方动态生成。(这点,组里优秀的小伙伴已经基本实现。是先配置在系统专门维护的方法表里,然后供页面选择)当然,我也在思考,如何通过注解,反射等机制把这个事情自动化,不要要挨个去录入。我觉得如果有机会,可以这样去做吧!
- 规则进一步抽象独立出来,用来适应更复杂的场景和更复杂度规则执行。
- 尽量剥离系统中业务接口的直接引用,保持系统轻量化。完善RPC动态注册配置,避免jar包引入方式。
其实还有好多需要优化的点,却有难以一时总结清晰,后续更新吧…
系统已经灰度发布,截至目前为止,报警全部来自业务方接口调用失败,异常。当然,后续的大流量能否抗住,还要持续观测与优化,也是对我最大的考验。
未完…待续…
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 10张图带你了解后台服务架构演变
- 微信架构总监:微信 10 亿日活场景下,后台系统微服务架构实践
- 微信架构总监:微信 10 亿日活场景下,后台系统微服务架构实践
- 头条后台研发面经(共三面)+架构师进阶路线分享
- 如何架构一个中后台项目的前端部分(技术选型篇)
- 如何架构一个中后台项目的前端部分(接口配置篇)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms on Strings, Trees and Sequences
Dan Gusfield / Cambridge University Press / 1997-5-28 / USD 99.99
String algorithms are a traditional area of study in computer science. In recent years their importance has grown dramatically with the huge increase of electronically stored text and of molecular seq......一起来看看 《Algorithms on Strings, Trees and Sequences》 这本书的介绍吧!