不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • Python

  • GO

  • Java

  • 业务问题

  • 关键技术

    • 01.接口幂等
      • 02.消息重复消费
        • 1、问题说明
        • 2、redis解决方案
    • 02.支付中分布式事务
    • 03.限流
    • 04.断点续传
    • 05.连接池设计
  • 项目常识

  • 计算机基础

  • 常识
  • 关键技术
xiaonaiqiang
2024-02-07
目录

01.接口幂等

  • 后端唯一订单号:预生成全局唯一订单号,利用数据库唯一索引防重,彻底解决但方案复杂

  • 前端唯一订单号:前端生成唯一订单号,简化方案但需前后端协作

  • 业务标识:使用“用户ID+商品ID”作为唯一标识,依赖Redis防重,无需新增字段或接口

  • 消息重复消费问题可通过Redis解决

    • 生成唯一消息ID,存储消息状态(0:处理中,1:已消费),处理完后手动ack确认
    • 极高要求系统需持久化消息ID,两者均依赖幂等性设计,确保系统一致性

# 01.订单重复创建

# 0、幂等

  • 接口幂等是什么
    • 以相同的参数,对一个接口进行多次调用,所产生的结果和一次调用是完全相同的
  • 重复提交的两种原因
    • 一种是由于用户在短时间内多次点击下单按钮,或浏览器刷新按钮导致
    • 另一种则是由于Nginx或类似于SpringCloud Gateway的网关层,进行超时重试造成的

# 1、后端唯一订单号

  • 后端新增一个接口,用于预生成一个“全局唯一订单号”
  • 进入创建订单页面时,前端请求该接口,获取该订单号
  • 在提交订单时,请求参数里要带上这个预生成的“全局唯一订单号”
  • 利用数据库的唯一索引特性,在插入订单记录时,如果该“全局唯一的订单号”重复,记录会插入失败

优点:彻底解决了重复下单的问题;

缺点:方案复杂,前后端都有开发工作量,还要新增接口,新增字段

# 2、前端唯一订单号

  • 用户进入下页面时,前端程序自己生成一个“全局唯一订单号”
  • 利用数据库的唯一索引特性,在插入订单记录时,如果该“全局唯一的订单号”重复,记录会插入失败

优点:彻底解决了重复下单的问题,且技术方案做了一定简化;

缺点:前后端仍然都有开发工作量,且需要新增字段;

# 3、从订单业务的本质入手

  • 可以用 ”用户ID + 分隔符 + 商品ID“ 作为唯一标识
  • 让持有相同标识的请求在短时间内不能重复下单

优点:彻底解决了重复下单的问题,且在技术方案上,不需要前端参与,不需要添加接口,不需要添加字段

缺点:综合比较而言,暂无明显缺点,如果硬要找缺点的话,可能强依赖于Redis勉强可以算上吧

# 02.消息重复消费

# 1、问题说明

  • 在分布式系统中,消息队列扮演着重要的角色,它能够实现系统间的解耦和异步通信
  • 然而,由于网络、硬件和服务故障等原因,消息在传递过程中可能会发生重复消费的情况
  • 这会导致系统中的数据出现不一致性,并产生预期之外的副作用

# 2、redis解决方案

  • 生成者在发送每一条消息之前,生成一个唯一的消息ID
  • 使用redis的hash结构存储
    • key: 消息唯一ID
    • value:
      • 0:有其他任务再消费(可以直接忽略该消息)
      • 1:消息已经被消费(这个时候可以手动ack确认)
  • 处理完消息后,将缓存中这个消息的值修改为1,最后手动ack确认消息成功消费
  • 在存储消息ID时,可以设置过期时间,以便自动清理不需要的数据
  • 这种方案理论上依然会存在重复消费问题
    • 一般使用redis缓存是会设置消息ID的过期时间,如果过期后依然会出现重复消费问题
    • 如果系统有极强的要求,可能还需要配合持久化消息(比如通过mysql来记录消息ID+状态变更)

注:redis缓存方案性能比较好,如果有极高要求的系统,可以使用持久化消息ID来替代

上次更新: 2025/2/19 16:42:39
15.十亿数据批量写入mysql
02.支付中分布式事务

← 15.十亿数据批量写入mysql 02.支付中分布式事务→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式