幂等概述

  • 幂等性原本是数学上的概念,即使公式:f(x)=f(f(x)) 能够成立的数学性质。用在编程领域,则意为对同一个系统,使用同样的条件,一次请求和重复的多次请求对系统资源的影响是一致的。

  • 幂等性是分布式系统设计中十分重要的概念,具有这一性质的接口在设计时总是秉持这样的一种理念:调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生

  • 实现幂等的方式很多,目前基于请求令牌机制适用范围较广。其核心思想是为每一次操作生成一个唯一性的凭证,也就是 token。一个 token 在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果(报错)等。参考《幂等性浅谈》

幂等处理实现

加入依赖

  1. <dependency>
  2. <groupId>com.pig4cloud.plugin</groupId>
  3. <artifactId>idempotent-spring-boot-starter</artifactId>
  4. <version>0.0.1</version>
  5. </dependency>

配置 Redis 链接

  1. spring:
  2. redis:
  3. host: 127.0.0.1
  4. port: 6379

接口

  1. @Idempotent(key = "#key", expireTime = 10, info = "请勿重复查询")
  2. @GetMapping("/test")
  3. public String test(String key) {
  4. return "success";
  5. }

测试

  • 10 个独立线程请求

  • 执行查看结果,10 个请求只会有一个成功

  • 查看后台异常报错,9 个异常报错满足预期

idempotent 注解说明

  • key: 幂等操作的唯一标识,使用 spring el 表达式 用#来引用方法参数 。 可为空则取当前 url + args 做请求的唯一标识

  • expireTime: 有效期 默认:1 有效期要大于程序执行时间,否则请求还是可能会进来

  • timeUnit: 时间单位 默认:s (秒)

  • info: 幂等失败提示信息,可自定义

  • delKey: 是否在业务完成后删除 key true:删除 false:不删除

幂等处理设计原理

流程设计参考

  • 1.请求开始前,根据 key 查询 查到结果:报错 未查到结果:存入 key-value-expireTime key=ip+url+args

  • 2.请求结束后,直接删除 key 不管 key 是否存在,直接删除 是否删除,可配置

  • 3.expireTime 过期时间,防止一个请求卡死,会一直阻塞,超过过期时间,自动删除 过期时间要大于业务执行时间,需要大概评估下;

  • 4.此方案直接切的是接口请求层面。

  • 5.过期时间需要大于业务执行时间,否则业务请求 1 进来还在执行中,前端未做遮罩,或者用户跳转页面后再回来做重复请求 2,在业务层面上看,结果依旧是不符合预期的。

  • 6.建议 delKey = false。即使业务执行完,也不删除 key,强制锁 expireTime 的时间。预防 5 的情况发生。

  • 7.实现思路:同一个请求 ip 和接口,相同参数的请求,在 expireTime 内多次请求,只允许成功一次。

  • 8.页面做遮罩,数据库层面的唯一索引,先查询再添加,等处理方式应该都处理下。

  • 9.此注解只用于幂等,不用于锁,100 个并发这种压测,会出现问题,在这种场景下也没有意义,实际中用户也不会出现 1s 或者 3s 内手动发送了 50 个或者 100 个重复请求,或者弱网下有 100 个重复请求;

总结

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

Spring Boot 接口幂等插件使用的更多相关文章

  1. spring boot 整合pagehelper分页插件

    Spring Boot 整合pagehelper分页插件 测试环境: spring boot  版本 2.0.0.M7 mybatis starter 版本  1.3.1 jdk 1.8 ------ ...

  2. spring boot集成mybatis分页插件

    mybatis的分页插件能省事,本章记录的是 spring boot整合mybatis分页插件. 1.引入依赖 <!-- 分页插件pagehelper --> <dependency ...

  3. spring boot 接口返回值封装

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  4. Spring Boot MyBatis 通用Mapper插件集成 good

    看本文之前,请确保你已经在SpringBoot中集成MyBatis,并能正常使用.如果没有,那么请先移步 http://blog.csdn.net/catoop/article/details/505 ...

  5. spring boot 接口返回值去掉为null的字段

    现在项目都是前后端分离的,返回的数据都是使用json,但有些接口的返回值存在 null或者"",这种字段不仅影响理解,还浪费带宽,需要统一做一下处理,不返回空字段,或者把NULL转 ...

  6. 前端页面调用Spring boot接口发生的跨域问题

    最近要重构一个基于spring boot的后端API服务,需要再本地测试.在本地测试时,运行在本地的前端页面发送一个ajax请求访问后端API,然后浏览器报错blocked CORS policy. ...

  7. spring boot:接口站增加api版本号后的安全增强(spring boot 2.3.3)

    一,接口站增加api版本号后需要做安全保障? 1,如果有接口需要登录后才能访问的, 需要用spring security增加授权 2,接口站需要增加api版本号的检验,必须是系统中定义的版本号才能访问 ...

  8. Spring Boot XSS 攻击过滤插件使用

    XSS 是什么 XSS(Cross Site Scripting)攻击全称跨站脚本攻击,为了不与 CSS(Cascading Style Sheets)名词混淆,故将跨站脚本攻击简称为 XSS,XSS ...

  9. spring boot中利用mybatis-generator插件生成代码

    使用Idea在spring boot中集成mybatis-generator,自动生成mapper.xml  model  dao 文件 一.配置 pom.xml 在pom.xml的<plugi ...

随机推荐

  1. django学习-15.ORM查询方法汇总

    1.前言 django的ORM框架提供的查询数据库表数据的方法很多,不同的方法返回的结果也不太一样,不同方法都有各自对应的使用场景. 主要常用的查询方法个数是13个,按照特点分为这4类: 方法返回值是 ...

  2. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片

    知识点梳理 课堂讲义 1.JQuery快速入门 1.1.JQuery介绍 jQuery 是一个 JavaScript 库. 框架:Mybatis (jar包) 大工具 插件:PageHelper (j ...

  3. JS相关基础

    1. ES5和ES6继承方式区别 ES5定义类以函数形式, 以prototype来实现继承 ES6以class形式定义类, 以extend形式继承 2. Generator了解 ES6 提供的一种异步 ...

  4. MVVM中的vm双向监听和mvc的缺点

    `MVVM`模型: - 即Model,模型,包括数据和一些基本操作 - 即View,视图,页面渲染结果- 即View-Model,模型与视图间的双向操作(无需开发人员干涉) `MVVM`中的`VM`要 ...

  5. 文字链接Link

    效果展示: 代码展示: <el-table-column label="引流扫码人数" align="center"> <template s ...

  6. Autocad中使用命令来调用python对Autocad二次开发打包后的exe程序

    在Autocad中直接调用Python二次开发程序是有必要的,下面介绍一种方法来实现这个功能: 其基本思路是:先将二次开发的程序打包为可执行程序exe,然后编写lsp文件,该文件写入调用exe程序的语 ...

  7. 后端程序员之路 28、一个轻量级HTTP Server的实现

    提到http server,一般用到的都是Apache和nginx这样的成熟软件,但是,有的情况下,我们也许也会用一些非常轻量级的http server.http server的c++轻量级实现里,M ...

  8. ClickHouse源码笔记4:FilterBlockInputStream, 探寻where,having的实现

    书接上文,本篇继续分享ClickHouse源码中一个重要的流,FilterBlockInputStream的实现,重点在于分析Clickhouse是如何在执行引擎实现向量化的Filter操作符,而利用 ...

  9. 通过golang小案例,了解golang程序常见机制

    目录 代码理解及纠错 1.defer和panic执行先后顺序 2.for循环元素副本问题 3.slice追加元素问题 4.返回值命名问题 5.用new初始化内置类型问题 6.切片append另外一个切 ...

  10. js和c#小数四舍五入

    <script language="javascript"> document.write("<h1>JS保留两位小数例子</h1>& ...