redistemplate使用_如何使用 SpringBoot + Redis 优雅的解决接口幂等性问题

v2-05315e3a84af2293d7f3da48c0db268b_1440w.jpg?source=172ae18b

# 前言

在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段:

  1. 数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据
  2. token机制,每次接口请求前先获取一个token,然后再下次请求的时候在请求的header体中加上这个token,后台进行验证,如果验证通过删除token,下次请求再次判断token
  3. 悲观锁或者乐观锁,悲观锁可以保证每次for update的时候其他sql无法update数据(在数据库引擎是innodb的时候,select的条件必须是唯一索引,防止锁全表)
  4. 先查询后判断,首先通过查询数据库是否存在数据,如果存在证明已经请求过了,直接拒绝该请求,如果没有存在,就证明是第一次进来,直接放行。

redis实现自动幂等的原理图:

v2-bd39474d1d9ed4c4988b28b369a1b22b_b.jpg

# 搭建redis的服务Api

1、首先是搭建redis服务器。

2、引入springboot中到的redis的stater,或者Spring封装的jedis也可以,后面主要用到的api就是它的set方法和exists方法,这里我们使用springboot的封装好的redisTemplate

/**

# 自定义注解AutoIdempotent

自定义一个注解,定义此注解的主要目的是把它添加在需要实现幂等的方法上,凡是某个方法注解了它,都会实现自动幂等。后台利用反射如果扫描到这个注解,就会处理这个方法实现自动幂等,使用元注解ElementType.METHOD表示它只能放在方法上,etentionPolicy.RUNTIME表示它在运行时

@Target

# token创建和检验

1、token服务接口

我们新建一个接口,创建token服务,里面主要是两个方法,一个用来创建token,一个用来验证token。创建token主要产生的是一个字符串,检验token的话主要是传达request对象,为什么要传request对象呢?主要作用就是获取header里面的token,然后检验,通过抛出的Exception来获取具体的报错信息返回给前端

public 

2、token的服务实现类

token引用了redis服务,创建token采用随机算法工具类生成随机uuid字符串,然后放入到redis中(为了防止数据的冗余保留,这里设置过期时间为10000秒,具体可视业务而定),如果放入成功,最后返回这个token值。checkToken方法就是从header中获取token到值(如果header中拿不到,就从paramter中获取),如若不存在,直接抛出异常。这个异常信息可以被拦截器捕捉到,然后返回给前端。

@Service

# 拦截器的配置

1、web配置类

实现WebMvcConfigurerAdapter,主要作用就是添加autoIdempotentInterceptor到配置类中,这样我们到拦截器才能生效,注意使用@Configuration注解,这样在容器启动是时候就可以添加进入context中

@Configuration

2、拦截处理器

主要的功能是拦截扫描到AutoIdempotent到注解到方法,然后调用tokenService的checkToken()方法校验token是否正确,如果捕捉到异常就将异常信息渲染成json返回给前端

/**

# 测试用例

1、模拟业务请求类

首先我们需要通过/get/token路径通过getToken()方法去获取具体的token,然后我们调用testIdempotence方法,这个方法上面注解了@AutoIdempotent,拦截器会拦截所有的请求,当判断到处理的方法上面有该注解的时候,就会调用TokenService中的checkToken()方法,如果捕获到异常会将异常抛出调用者,下面我们来模拟请求一下:

@RestController

2、使用postman请求

首先访问get/token路径获取到具体到token:

v2-4af35f82d9186250488573bf51977b31_b.jpg

利用获取到到token,然后放到具体请求到header中,可以看到第一次请求成功,接着我们请求第二次:

v2-24f20709fe500b04933ec821b26b49d5_b.jpg

第二次请求,返回到是重复性操作,可见重复性验证通过,再多次请求到时候我们只让其第一次成功,第二次就是失败:

v2-35d710996e6ea48692638fe00b7edb75_b.jpg

# 总结

本篇博客介绍了使用springboot和拦截器、redis来优雅的实现接口幂等,对于幂等在实际的开发过程中是十分重要的,因为一个接口可能会被无数的客户端调用,如何保证其不影响后台的业务处理,如何保证其只影响数据一次是非常重要的,它可以防止产生脏数据或者乱数据,也可以减少并发量,实乃十分有益的一件事。而传统的做法是每次判断数据,这种做法不够智能化和自动化,比较麻烦。而今天的这种自动化处理也可以提升程序的伸缩性。


原作者:慕容千语
原文链接:Spring Boot+Redis+Interceptor+自定义Annotation实现接口自动幂等
原出处:简书
侵删

v2-4d4cccb2b9aae3b11741e93b2f876ed0_b.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427365.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 创建类_python 用type()创建类

type()可以查看一个类型,也可以查看变量的类型class Hello1(object):def hello(self, name world):print(Hello, %s % name)h1 Hello1()h1.hello()print(type(Hello1))print(type(h1))输出:Hello, world#Hello是一个class, 它的类型就是typ…

关于c语言中如何四舍五入(圆整)的问题!

关于c语言中如何四舍五入(圆整)的问题! 在c语言中,用70.0/6得到的值赋给一个浮点变量,只会得到11.666667(因为浮点型只留下小数点后六位),而如果我们想输出结果的约数,必须要对结果进行四舍五入. 一般来说,在c语言中,如果想要对一个结果进行四舍五入,我们通常会先将需要圆整的…

图像的灰度级和动态范围(转)

学习笔记(一)——图像的灰度级和动态范围转载于:https://www.cnblogs.com/LittleTiger/p/9359712.html

jdbctemplate 开启事务_SpringBoot 系列教程之事务隔离级别知识点小结

上一篇博文介绍了声明式事务Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上,并通过实例演示不同的事务隔离级别下,脏读、不可重复读、幻读的具体场景I. 基础知识在进入…

东风小康为什么是dfsk_助力地摊经济瑞驰纯电动物流车和东风小康微型货车厚积薄发...

核心提示:小康集团旗下瑞驰纯电动物流车及东风小康微型货车深耕多年,其中瑞驰纯电动物流车2015年上市,连续多年销量位列中国行业第一。近日,地摊经济成为热门,疫情常态化下,地摊经济、小店经济对于快速恢复…

链表中删除选定结点的优雅操作!

一般我们在进行单向链表链表的结点删除操作时,都是通过相应的结构体指针进行链表的遍历,然后找 到需要删除的节点,为了完成删除操作,我们需要在寻找该节点时,不断地记录下这个节点前面的节点 (prev),来保证当特定结点被删除后,我们还可以将断开的链表重新连起来,下面给出一段…

python抢货程序_Python自动化xpath实现自动抢票抢货代码示例

本篇文章小编给大家分享一下Python自动化xpath实现自动抢票抢货代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。 总代码: for i in range(51,56): driver.imp…

Ubuntu安装pycharm并且激活

下载pycharm: https://www.jetbrains.com/pycharm/download/#sectionlinux 选择专业版下载,然后提取,也就是解压 进入解压后目录,再进入bin目录,打开终端执行命令 ./pycharm.sh pycharm就启动了 激活Pycharm: 编辑hosts文件&am…

二阶矩阵转置怎么求_矩阵求导术(下)

点击上方“Datawhale”,选择“星标”公众号第一时间获取价值内容本文承接上篇 https://zhuanlan.zhihu.com/p/24709748,来讲矩阵对矩阵的求导术。使用小写字母x表示标量,粗体小写字母表示列向量,大写字母X表示矩阵。矩阵对矩阵的求…

洛谷-DFS-1019-单词接龙-个人AC题解和公共AC题解笔记

学习内容: 预处理万能头文件string的使用 话不多说,直奔主题 本人AC代码 #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 21 #define MAXLENGTH 21 int n; int length,max_length; char words[MAXN][MAXLEN…

c语言中x的n次方怎么表示_线性代数的本质及其在人工智能中的应用

线性代数是 AI 专家必须掌握的知识&#xff0c;这已不再是个秘密。如果不掌握应用数学这个领域&#xff0c;你永远就只能是「门外汉」。当然&#xff0c;学习线性代数道阻且长。数学&#xff0c;尤其是线性代数常与枯燥、复杂和毫无意义的事物联系起来。不过你还可以另辟蹊径。…

js之箭头函数

原文 ES6标准新增了一种新的函数&#xff1a;Arrow Function&#xff08;箭头函数&#xff09;。 为什么叫Arrow Function&#xff1f;因为它的定义用的就是一个箭头&#xff1a; x > x * x 上面的箭头函数相当于&#xff1a; function (x) {return x * x; } 箭头函数相当于…

android开发蓝牙是否可见开关_如何从后台开启android蓝牙的可见性以及始终保持可见性...

最近工作中遇到一个特殊的需求&#xff0c;要求代码能够从后台开机android手机蓝牙的可见性。而framework提供了一种打开可见性的操作&#xff0c;就是通过向用户弹出一个提示框&#xff0c;来询问是否允许开启可见性。而且限制了最长时间为300秒&#xff0c;代码如下&#xff…

洛谷-DFS-1101-单词方阵-个人AC题解及公共题解的笔记

先上自己AC代码(博主这个代码修改过多次,只因代码长度过长) #include<bits/stdc.h> using namespace std; #define MAXN 102 int flag; int n; int next1[8][2]{{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; char map1[MAXN][MAXN],map2[MAXN][MAXN]; cons…

django 实现电子支付功能

思路&#xff1a;调用第三方支付 API 接口实现支付功能。本来想用支付宝来实现第三方网站的支付功能的&#xff0c;但是在实际操作中发现支付宝没有 Python 接口&#xff0c;网上虽然有他人二次封装的的 Python 接口&#xff0c;但是对我这个小白白来说上手还是有点难度&#x…

android中怎么保存checkbox中的checked属性_第二十四天HTML中的form表单

form表单用于收集用户信息&#xff0c;如&#xff1a;登录、注册等场景&#xff1b;所有要提交的数据都必须放在form标签中action&#xff1a;提交地址、动作&#xff0c;与input标签中typy标签的submit属性相关联。 &#xff0c;提交地址是action的地址method:提交方法&#x…

Python中曲率与弯曲的转换_1000R曲率更具沉浸感!三星T55曲面显示器评测

在曲面屏的设计上&#xff0c;三星一直在突破极限&#xff0c;比如在2017年推出的49英寸超宽带鱼屏C49HG90&#xff0c;引来众人围观&#xff0c;非常震撼。而在曲率方面&#xff0c;我们常见的有1800R和1500R&#xff0c;但是三星并不满足&#xff0c;于日前推出了一款曲率达到…

树的遍历-Preorde Traversal,Inorder Traversal,Postoder Traversal

上代码(创建树,先序,中序,后序) #include<bits/stdc.h> using namespace std; typedef struct TreeNode *BinTree; struct TreeNode {BinTree left,right;int value; }; BinTree CreateTree() {BinTree T;int value;cin>>value;if(value0) //如果输入0,则创…

opencv resize_opencv-python库基础操作(一)

点赞再看&#xff0c;养成习惯&#xff01;点赞再看&#xff0c;养成习惯&#xff01;点赞再看&#xff0c;养成习惯&#xff01;opencv-python库基础操作0.安装opencv-pythonpip install opencv-python进行下载并安装不过在python中导入opencv库的时候需要"import cv2&qu…

Page object设计模式

网上看了很多文章&#xff0c;充斥了大量代码。理解起来不容易&#xff0c;在此就我的理解谈谈PageObject设计模式到底是什么东西。 所谓的Page object模式&#xff0c;主要是编写不同层级的脚本&#xff0c;然后一层一层的继承来完成对web测试过程进行分解。 首先&#xff1a;…