网站公司用什么软件做网站,网站建设首选原创先锋,购物网站设计模版,焦作网站设计公司关于重复请求#xff0c;指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同#xff0c;如查询请求)#xff0c;那其实对于我们没有什么影响#xff0c;但如果是非幂等的(每次请求都会对关键数据造成影响指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同如查询请求)那其实对于我们没有什么影响但如果是非幂等的(每次请求都会对关键数据造成影响如删除关系、建立关系等)那就会轻则产生脏数据重则导致系统错误。因此在当前普遍分布式服务的情况下如何避免和解决重复请求给我们带来的数据异常成为了亟待解决的问题。而避免重复请求最好的做法是前后端共同去做。1. 前端或客户端在非幂等的按钮上直接做禁止提交重复请求的操作。2. 后端在接收到请求时加锁完成后解锁。这篇博客主要讲的是在后端基于分布式锁的概念去出一个关于解决重复请求的通用解决方案。二、正文为何要使用分布式锁来解决呢因为我们当前普遍的架构都是分布式的服务端前端请求通过网关层转发至后端如下图所示因此如果只在一个单独的服务器上做限制就无法在分布式的服务中完成应对高频次的重复请求了。基本思路思路基本上是对需要做防止重复请求的接口加上分布式锁步骤如下在接收到请求后根据方法名参数取md5值获取该方法及该参数的唯一标识获取标识后设置分布式锁并且设置过期时间在请求结束后释放分布式锁。即可完成对当前请求的重复请求禁止。如果想做通用的解决方案那就需要把上述步骤做出一个小功能出来由于本人对java、spring框架比较熟悉就拿这个来做个示例。基于spring切面、redis的实现想必一些熟悉spring的同学已经知道我想采用什么方式了做通用型的肯定要用到spring的aop特性注解切面md5key反射redis实现具体如下定义一个分布式锁注解注解包含过期时间设置、忽略参数定义一个切面切点为分布式锁注解在切面中获取需要使用分布式锁的方法名、参数、过期时间并且将方法名及未被忽略参数做md5取唯一标识再根据上述唯一标识设置redsis分布式锁方法结束后解锁。代码如下注解定义名称为RepeatOperationLock的注解参数有锁过期时间及忽略属性(即不参与分布式锁标识MD5计算的属性)。DocumentedInheritedRetention(RetentionPolicy.RUNTIME)Target({ElementType.METHOD})Componentpublic interface RepeatOperationLock { /** * 锁时长默认500ms * return */ long timeOut() default 500; /** * 忽略上锁参数位置从0开始 * return */ int[] ignoreIndex();}复制代码切面切点为上述注解切面中做了以下几件事获取方法名、获取注解属性(过期时间、忽略属性)、计算方法属性的md5值、调用外部分布式锁的方法。AspectSlf4jComponentpublic class LockAspect { Autowired RepeatLockService repeatLockService; Pointcut(annotation(com.ls.javabase.aspect.annotation.RepeatOperationLock)) public void serviceAspect() { } Before(serviceAspect()) public void setLock(JoinPoint point) { log.info(防止方法重复调用接口锁,上锁,point:{}