Spring Boot+Redis 扛住,瞬间千次重复提交

本文介绍如何利用Spring Boot、Redis和拦截器实现接口幂等性,以防止重复请求对业务造成影响。文章详细讲解了幂等概念、Redis服务API的搭建、自定义注解、token的创建和检验、拦截器配置以及测试用例,提供了一种自动化处理接口幂等的方法,以提高程序的伸缩性和避免脏数据产生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:慕容千语 

来源:http://suo.im/5PaEZI

 

前言:

在实际的开发项目中,一个对外暴露的接口往往会面临,瞬间大量的重复的请求提交,如果想过滤掉重复请求造成对业务的伤害,那就需要实现幂等

我们来解释一下幂等的概念:

任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。

如何保证其幂等性,通常有以下手段:

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

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

一、搭建redis的服务Api

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

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

 
  1. /**

  2. * redis工具类

  3. */

  4. @Component

  5. public class RedisService {

  6.    @Autowired

  7.    private RedisTemplate redisTemplate;

  8.    /**

  9.     * 写入缓存

  10.     * @param key

  11.     * @param value

  12.     * @return

  13.     */

  14.    public boolean set(final String key, Object value) {

  15.        boolean result = false;

  16.        try {

  17.            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

  18.            operations.set(key, value);

  19.            result = true;

  20.        } catch (Exception e) {

  21.            e.printStackTrace();

  22.        }

  23.        return result;

  24.    }

  25.    /**

  26.     * 写入缓存设置时效时间

  27.     * @param key

  28.     * @param value

  29.     * @return

  30.     */

  31.    public boolean setEx(final String key, Object value, Long expireTime) {

  32.        boolean result = false;

  33.        try {

  34.            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();

  35.            operations.set(key, value);

  36.            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);

  37.            result = true;

  38.        } catch (Exception e) {

  39.            e.printStackTrace();

  40.        }

  41.        return result;

  42.    }

  43.    /**

  44.     * 判断缓存中是否有对应的value

  45.     * @param key

  46.     * @return

  47.     */

  48.    public boolean exists(final String key) {

  49.        return redisTemplate.hasKey(key);

  50.    }

  51.    /**

  52.     * 读取缓存

  53.     * @param key

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值