业务背景
之前做的一个企业内部用的综合配置系统,该系统的原版为前后端分离的单一服务架构(前端一个服务,后端一个服务)。由于业务拓展和数据处理的数量级增加,加之逻辑的复杂度增高,运算量也成本加大,所以该系统的重新构建成为了一个让人头疼又不得不开始思考的课题。
简单介绍下原来系统的架构,后端为.NET core webapi系统,用到的数据库为Mysql,此外还用到了Redis来做一级缓存,另加内存缓存来处理操作频繁或者对外提供的接口。
说一说之前系统运行中的问题
1.由于系统功能的延申,系统除了实现前端的功能以外,还需要对外提供若干个接口;
2.此外还有一些频繁的导入导出功能有时候会造成系统运行的卡顿;
3.有些一些需要定期处理,运算量大的程序之前是放在后台的一个线程中执行;
4.有一些功能出现异常或者触发阈值之后,需要给钉钉或者邮箱发送异常信息;
5.其他嵌套在程序中耗时,耗资源的需要解耦的服务;
0
简单介绍下优化之后的系统架构
0
1.根据之前的调研,页面操作对系统的压力不是那么大,综合考虑之后前后端总体的代码没有大的调整,仍然保持单服务模式即可;
Tip:这里我们考虑的是,如果前后端优化成多服务,需要考虑很多操作时的异步处理和唯一性验证问题,这样改造起来花的时间成本会比较大。如果有类似的需求,在改造前后端加负载均衡的时候,一定要考虑多个后端程序同时运行时的逻辑唯一性验证的问题,可以考虑假如布隆过滤器等手段。
2.将对外提供的接口单独出来作为可负载(可自动扩容)的单独服务,对外提供的接口,一般情况下都是读取数据,这样的话,单独出来便于以后的优化和部署管理,部署后压力大的时候,也方便扩容。
3.将复杂的业务逻辑单独成若干个后台程序(或者说控制台程序),后台程序与触发程序间通过Redis list来实现。
Tip:这边我们没有加入消息中间件,考虑的是首先加入新的中间件会大大增加系统的复杂度和不可控因素,其次是考虑成本问题,之前系统中已经使用了redis并且压力不大,就退而求其次的采用了redis队列加后台服务轮询的策略来实现了。(利用Redis的单线程特性,和对比MySql的高读取效率)
任务的生命周期大概如下:
任务生产者创建任务-》添加MySql任务记录(任务类型为初始话)-》获取到MySql任务记录的id,并创建相关的任务插入到Redis队列上=》后台服务根据任务类型,读取Redis队列,读取到任务就执行相应任务 =》执行完成后,根据任务中的MySql任务表id,将MySql记录表的数据修改状态(或者删除后添加到记录历史表,推荐这样)。
此外,我们这里添加了一个任务异常服务,该服务会定期去看MySql任务表中是否有异常任务,根据异常任务的异常类型,决定是否重新创建任务或者将任务记录做对应处理。
再说一些细节,比如导入导出服务,我们页面添加了一个导入导出的页面,用来处理那种大数据的导入导出,每个功能的导入导出,根据自己选择可以提供同步的导入导出(数据量少时),
同时也能够提供异步的导入导出(数据量大时)。异步的导入,导入的逻辑是,我们将页面导入的文件直接仍在OSS上,并创建导入处理任务,交由后台导入导出服务处理。同理,异步的导出也是如此,页面导入的请求只创建对应的导出任务,导入导出服务后台根据任务来生成对应的文件,扔到OSS上,任务完成后,可以在导入导出页面中,点击对应的链接,这时候,才会将文件下载到当地。
 
 
 
posted on 2022-07-07 10:36  CRUDEngineer  阅读(130)  评论(0编辑  收藏  举报