
在解决这类问题的时候,有一种比较简单的方式,那就是通过业务上的被动方式来进行关单 *** 作。
简单点说,就是订单创建好了之后。我们系统上不做主动关单,什么时候用户来访问这个订单了,再去判断时间是不是超过了过期时间,如果过了时间那就进行关单 *** 作,然后再提示用户。
ec057b3bd928d355c7b48cb90db09075.jpeg
这种做法是最简单的,基本不需要开发定时关闭的功能,但是他的缺点也很明显,那就是如果用户一直不来查看这个订单,那么就会有很多脏数据冗余在数据库中一直无法被关单。
还有一个缺点,那就是需要在用户的查询过程中进行写的 *** 作,一般写 *** 作都会比读 *** 作耗时更长,而且有失败的可能,一旦关单失败了,就会导致系统处理起来比较复杂。
所以,这种方案只适合于自己学习的时候用,任何商业网站中都不建议使用这种方案来实现订单关闭的功能。
基于 Spring Boot + MyBatis Plus + Vue &Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
二、定时任务
定时任务关闭订单,这是很容易想到的一种方案。
具体实现细节就是我们通过一些调度平台来实现定时执行任务,任务就是去扫描所有到期的订单,然后执行关单动作。
3c2bee58f0583da028071dcb24650d1e.jpeg
这个方案的优点也是比较简单,实现起来很容易,基于Timer、ScheduledThreadPoolExecutor、或者像xxl-job这类调度框架都能实现,但是有以下几个问题:
1、时间不精准。 一般定时任务基于固定的频率、按照时间定时执行的,那么就可能会发生很多订单已经到了超时时间,但是定时任务的调度时间还没到,那么就会导致这些订单的实际关闭时间要比应该关闭的时间晚一些。
2、无法处理大订单量。 定时任务的方式是会把本来比较分散的关闭时间集中到任务调度的那一段时间,如果订单量比较大的话,那么就可能导致任务执行时间很长,整个任务的时间越长,订单被扫描到时间可能就很晚,那么就会导致关闭时间更晚。
3、对数据库造成压力。 定时任务集中扫表,这会使得数据库IO在短时间内被大量占用和消耗,如果没有做好隔离,并且业务量比较大的话,就可能会影响到线上的正常业务。
4、分库分表问题。 订单系统,一旦订单量大就可能会考虑分库分表,在分库分表中进行全表扫描,这是一个极不推荐的方案。
所以,定时任务的方案,适合于对时间精确度要求不高、并且业务量不是很大的场景中。如果对时间精度要求比较高,并且业务量很大的话,这种方案不适用。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue &Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
三、JDK自带的延迟队列
有这样一种方案,他不需要借助任何外部的资源,直接基于应用自身就能实现,那就是基于JDK自带的DelayQueue来实现
DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。
基于延迟队列,是可以实现订单的延迟关闭的,首先,在用户创建订单的时候,把订单加入到DelayQueue中,然后,还需要一个常驻任务不断的从队列中取出那些到了超时时间的订单,然后在把他们进行关单,之后再从队列中删除掉。
这个方案需要有一个线程,不断的从队列中取出需要关单的订单。一般在这个线程中需要加一个while(true)循环,这样才能确保任务不断的执行并且能够及时的取出超时订单。
使用DelayQueue实现超时关单的方案,实现起来简单,不须要依赖第三方的框架和类库,JDK原生就支持了。
当然这个方案也不是没有缺点的,首先,基于DelayQueue的话,需要把订单放进去,那如果订单量太大的话,可能会导致OOM的问题;另外,DelayQueue是基于JVM内存的,一旦机器重启了,里面的数据就都没有了。虽然我们可以配合数据库的持久化一起使用。而且现在很多应用都是集群部署的,那么集群中多个实例上的多个DelayQueue如何配合是一个很大的问题。
所以,基于JDK的DelayQueue方案只适合在单机场景、并且数据量不大的场景中使用,如果涉及到分布式场景,那还是不建议使用。
四、Netty的时间轮
还有一种方式,和上面我们提到的JDK自带的DelayQueue类似的方式,那就是基于时间轮实现。
为什么要有时间轮呢?主要是因为DelayQueue插入和删除 *** 作的平均时间复杂度——O(nlog(n)),虽然已经挺好的了,但是时间轮的方案可以将插入和删除 *** 作的时间复杂度都降为O(1)。
时间轮可以理解为一种环形结构,像钟表一样被分为多个 slot。每个 slot 代表一个时间段,每个 slot 中可以存放多个任务,使用的是链表结构保存该时间段到期的所有任务。时间轮通过一个时针随着时间一个个 slot 转动,并执行 slot 中的所有到期任务。
地址:cnblogs.com/iceblow/p/11121362.html
权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或 *** 作不当引发的风险问题,如 *** 作错误,隐私数据泄露等问题。 目前在公司负责权限这块,所以对权限这块的设计比较熟悉,公司采用微服务架构,权限系统自然就独立出来了,其他业务系统包括商品中心,订单中心,用户中心,仓库系统,小程序,多个APP等十几个系统和终端
迄今为止最为普及的权限设计模型是RBAC模型,基于角色的访问控制(Role-Based Access Control)
这是权限最基础也是最核心的模型,它包括用户/角色/权限,其中用户和角色是多对多的关系,角色和权限也是多对多的关系。
用户 是发起 *** 作的主体,按类型分可分为2B和2C用户,可以是后台管理系统的用户,可以是OA系统的内部员工,也可以是面向C端的用户,比如阿里云的用户。
角色 起到了桥梁的作用,连接了用户和权限的关系,每个角色可以关联多个权限,同时一个用户关联多个角色,那么这个用户就有了多个角色的多个权限。
有人会问了为什么用户不直接关联权限呢?在用户基数小的系统,比如20个人的小系统,管理员可以直接把用户和权限关联,工作量并不大,选择一个用户勾选下需要的权限就完事了。
但是在实际企业系统中,用户基数比较大,其中很多人的权限都是一样的,就是个普通访问权限,如果管理员给100人甚至更多授权,工作量巨大。
这就引入了"角色(Role)"概念,一个角色可以与多个用户关联,管理员只需要把该角色赋予用户,那么用户就有了该角色下的所有权限,这样设计既提升了效率,也有很大的拓展性。
权限 是用户可以访问的资源,包括页面权限, *** 作权限,数据权限:
以上是RBAC的核心设计及模型分析,此模型也叫做RBAC0,而基于核心概念之上,RBAC还提供了扩展模式。包括RBAC1,RBAC2,RBAC3模型。下面介绍这三种类型
此模型引入了角色继承(Hierarchical Role)概念,即角色具有上下级的关系,角色间的继承关系可分为一般继承关系和受限继承关系。
一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。
而受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承。这种设计可以给角色分组和分层,一定程度简化了权限管理工作。
基于核心模型的基础上,进行了角色的约束控制,RBAC2模型中添加了责任分离关系。
其规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。
责任分离包括静态责任分离和动态责任分离。主要包括以下约束:
即最全面的权限管理,它是基于RBAC0,将RBAC1和RBAC2进行了整合。
当平台用户基数增大,角色类型增多时,而且有一部分人具有相同的属性,比如财务部的所有员工,如果直接给用户分配角色,管理员的工作量就会很大。
如果把相同属性的用户归类到某用户组,那么管理员直接给用户组分配角色,用户组里的每个用户即可拥有该角色,以后其他用户加入用户组后,即可自动获取用户组的所有角色,退出用户组,同时也撤销了用户组下的角色,无须管理员手动管理角色。
根据用户组是否有上下级关系,可以分为有上下级的用户组和普通用户组:
每个公司都会涉及到到组织和职位,下面就重点介绍这两个。
常见的组织架构如下图:
我们可以把组织与角色进行关联,用户加入组织后,就会自动获得该组织的全部角色,无须管理员手动授予,大大减少工作量,同时用户在调岗时,只需调整组织,角色即可批量调整。
组织的另外一个作用是控制数据权限,把角色关联到组织,那么该角色只能看到该组织下的数据权限。
假设财务部的职位如下图:
每个组织部门下都会有多个职位,比如财务部有总监,会计,出纳等职位,虽然都在同一部门,但是每个职位的权限是不同的,职位高的拥有更多的权限。
总监拥有所有权限,会计和出纳拥有部分权限。特殊情况下,一个人可能身兼多职。
根据以上场景,新的权限模型就可以设计出来了,如下图:
根据系统的复杂度不同,其中的多对多关系和一对一关系可能会有变化
授权即给用户授予角色,按流程可分为手动授权和审批授权。权限中心可同时配置这两种,可提高授权的灵活性。
有了上述的权限模型,设计表结构就不难了,下面是多系统下的表结构,简单设计下,主要提供思路:
在项目中可以采用其中一种框架,它们的优缺点以及如何使用会在后面的文章中详细介绍。
权限系统可以说是整个系统中最基础,同时也可以很复杂的,在实际项目中,会遇到多个系统,多个用户类型,多个使用场景,这就需要具体问题具体分析,但最核心的RBAC模型是不变的,我们可以在其基础上进行扩展来满足需求。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)