IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 分布式接口幂等性的实现 -> 正文阅读

[大数据]分布式接口幂等性的实现

接口幂等性

幂等性:f(f(x)) = f(x),幂等元素运行多次,还等于它原来的运算结果。在系统中,一个接口运行多次,与运行一次的效果是一致的。

什么时候需要幂等性?

并不是所有的接口都要求幂等性,要根据业务设计。重复提交、接口重试、前端操作抖动等场景,例如用户一次提交一个订单,支付时只能扣一次钱。

幂等性策略

核心思想:通过**唯一的业务单号**保证幂等性。

非并发的情况,可以查询某个业务是否操作过,没有则执行(查询券是否使用过);并发时,操作过程加锁(分布式锁)。

select操作,不对数据有影响,天然幂等。

delete操作,第一次删除的话,不存在幂等性问题。

update操作

1、有唯一业务号的update操作

直接赋值是幂等的;set数据自增,不幂等。

策略是更新操作传入数据版本号,通过乐观锁实现幂等性。

2、没有唯一业务号,同下。

insert操作的幂等性

1、有唯一业务号的insert操作,例如:秒杀,商品ID+用户id

实现方式:

可通过分布式锁,保证接口幂等

业务执行完成后,不进行锁释放,让其自动过期释放

2、没有唯一业务号的insert操作,如用户注册,点击多次。

实现方式:没有唯一业务号,就要创建唯一业务号。

使用Token机制,保证幂等性

进入到注册页,后台统一生成Token,返回前台隐藏域中;用户提交,将token一同传入后台;使用token获取分布式锁,完成Insert操作

执行成功后,不释放锁,等待过期自动释放

3、混合操作幂等性

同样使用token机制。获取分布式锁,没有获取锁的就返回失败。

利用Token实现幂等性

假设用户提交订单前没有唯一业务id,此时可以考虑使用Token做幂等校验,创建一个唯一的业务id。

思路:用户进入订单提交页面,请求后端接口,根据sessionId保存一个Token到Redis中;用户提交订单时,携带Token,后端接口中校验Redis中Token与订单携带的Token是否一致,一致则允许订单操作,并删除Redis Token。

为了防止多次请求同时获取到同一个Redis Token,因此需要加分布式锁。

简要代码

@ApiOperation(value = "获取订单Token", notes = "获取订单Token", httpMethod = "POST")
@PostMapping("/getOrderToken")
public ServerResponse getOrderToken(HttpSession session) {
    String token = UUID.randomUUID().toString();
    redis.set("ORDER_TOKEN_" + session.getId(), token, 300);
    return ServerResponse.createBySuccess(token);
}

@ApiOperation(value = "用户提交订单", notes = "用户提交订单", httpMethod = "POST")
@PostMapping("/create")
public ServerResponse create(@RequestBody SubmitOrderBO submitOrderBO,
                             HttpServletRequest request,
                             HttpServletResponse response) {
    // 防止并发创建多个订单,加分布式锁
    String lockKey = "LOCK_KEY_" + request.getSession().getId();
    RLock lock = redissionClient.getLock(lockKey);
    lock.lock(5, TimeUnit.SECONDS);
    try {
        // 接口幂等性操作,校验Token
        String orderTokenKey = "ORDER_TOKEN_" + request.getSession().getId();
        String orderToken = redis.get(orderTokenKey);
        if (StringUtils.isBlank(orderToken)) {
            throw new RuntimeException("orderToken不存在");
        }
        if (!orderToken.equals(submitOrderBO.getToken())) {
            throw new RuntimeException("orderToken不正确");
        }
        // 请求正确后删除Token
        redis.del(orderTokenKey);
    } finally {
        lock.unlock(); // 也要try catch一下
    }
    
    // 其他订单校验、提交等操作。。。
}
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:46:24  更:2022-05-09 12:46:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:32:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码