spritekuang

导航

企业级自定义表单引擎解决方案(九)--缓存设计

  新年伊始,万物皆生机,然冠未去,美帝相向,于华夏之子,吾辈当自强。

  缓存对于任何一个系统来说,都是绕不开的一个话题,缓存设计好了对系统整体的性能往往是指数级的提升,但如是设计不好,对系统的稳定性和性能都是灾难性的影响,并直接影响系统整体的架构设计,这篇文章主要对自定义表单后端部分缓存的设计进行讨论,但缓存部分的设计思想并不限于自定义表单,其他类似的系统都可以进行参考。

  对于自定义表单来说,缓存比一般的系统依赖性更高,自定义表单定义产生的数据完全满足更新极少,查询极高的应用场景。可以想象,一个系统交付给客户之后,哪些情况还会重新发布,对于传统的项目,一般一年也没有几次,但是自定义表单时时刻刻都在查询,界面任何一个动作,都需要读取自定义表单数据的进行支撑,所以缓存对于自定义表单来说显得更加的重要,说到缓存,多数人第一印象就是Redis等缓存服务器,但自定义表单的缓存我这里的设计完全不依赖于外部缓存服务器,缓存部分的设计有别于其他系统的缓存设计。

先看一张实际效果图:

 

先说一下缓存部分的总体思想,然后再分析具体的代码实现。

  1. 自定义表单产生的数据汇总到表单和视图实体中(表单和视图的设计参考之前文章介绍),包括相关的控件、规则、行列数据、查询定义、界面控件样式等,都聚合到表单或视图中,表单和视图都会包含Id和Version字段,任何相关数据的变更,都会同步更新视图或表单数据,同时重新生成Version值。
  2. 将表单和视图实体的所有数据存储经过精简字段后存储到内存中(只存储逻辑上需要的字段。之所以选择存储到内存中,是因为自定义表单任何功能都需要读取定义数据,如果存储到Redis等外部缓存服务器,对外部服务器的访问量会非常大,且自定义表单数据定义往往不是几个字符,是很多数据聚合起来的,数据量相对来说比较大,且有些业务逻辑需要关联查询等,所以放到外部缓存服务器并不是可行的方案,所以这里选择存储到内存中),并以Dictionary<Id,实体>的方式开放接口访问,并按照应用模块来区分,相当于整个自定义表单的定义数据全部存储到内存中,会用到一些内存,但不会特别大,初步算了一下,100个页面,存储占用不会超过20M,对于现代服务器来说,不存在太大的问题。
  3. 自定义表单任何定义数据的更新,都会涉及到缓存的更新,对于单应用服务器不会存在任何的问题,但如果分布式部署的话就会引申出分布式缓存同步更新的问题,如果用独立的缓存服务器,也不会存在同步更新的问题,但这里的自定义表单缓存存储在应用服务内部,那么就需要借助于分布式的消息发布订阅功能的服务,自定义表单数据变更,发布变更通知,部署的自定义表单服务器订阅通知,收到变更通知时清楚自生内存缓存数据,等待读取缓存数据时,再从数据库读取数据更新缓存。分布式发布订阅的服务很多,可以选择Redis或者Rabbitmq等,这里的发布订阅可以不用是可靠的发布订阅。另外还需要处理发布订阅服务器断开问题,发布订阅服务器断开后,所有数据都直接读取数据库数据,这个时候应用系统会非常缓慢(解决方案?)。
  4. 前端访问每个自定义表单页面,读取表单关联的表单和视图数据,存储到IndexDb中,以KeyValue的形式存储,每请求一个页面,判断IndexDb中是否存在表单数据,存在时,将关联的表单Id和视图Id及其版本号传到后端,后端判断版本号是否与后端缓存的版本号一致,如果不一致,将最新的数据返回到前端,前端刷新IndexDb数据,然后再渲染数据。
  5. 前端每请求自定义表单后端接口数据时,将进入界面关联的表单Id和视图Id及其版本号写入Header,后端调用接口前进行拦截,判断版本号是有存在过期的情况,如果存在过期,则通知用户刷新界面,重新走加载页面判断版本号逻辑。这部分就是效果图看到的效果。

 

 

 

 

 

  自定义表单缓存设计的部分基本就介绍完了,还是涉及到比较多的逻辑点,这一块也是自定义表单的重点之一,整体来看,相对于传统方式开发的应用系统,性能上会有一些损失,但完全可以忽略,这部分内容有别于常规的缓存设计,但里面的一些设计思想还是可以应用到其他系统中,希望对于读者来说有一些用处。

  自定义表单的系列文章比较偏向于介绍设计思想,不是那么好阅读,干货比较多,这篇文章也主要介绍设计思路,下一篇文章具体再介绍一下代码的实现,谢谢你的阅读。

 

开源地址:https://gitee.com/kuangqifu/sprite

体验地址:http://47.108.141.193:8031(首次加载可能有点慢,用的阿里云最差的服务器)

自定义表单文章地址:https://www.cnblogs.com/spritekuang/

流程引擎文章地址:https://www.cnblogs.com/spritekuang/category/834975.html(采用WWF开发,已过时,已改用Elsa实现,https://www.cnblogs.com/spritekuang/p/14970992.html )

Github地址:https://github.com/kuangqifu/CK.Sprite.Job

posted on 2022-01-26 18:36  spritekuang  阅读(758)  评论(0编辑  收藏  举报