TP6.0 使用 Redis 实现分布式幂等性接口校验【防重放】

星枫小哥_5741

星枫小哥_5741

2026-07-13

538人浏览

原创

thinkphp 6.0 中通过 redis 实现分布式幂等性校验:客户端先获取唯一时效 token,业务接口用 lua 脚本原子性校验并删除 token,确保同一请求只执行一次;需结合中间件封装、命名空间隔离、redis 降级等机制保障可靠性。

tp6.0 使用 redis 实现分布式幂等性接口校验【防重放】

在 ThinkPHP 6.0 中使用 Redis 实现分布式幂等性接口校验,核心目标是:**同一业务请求(如下单、支付、提交表单)无论被重复发起多少次,后端只执行一次核心逻辑,且结果一致**。这不仅防重复提交,也具备防重放能力(即拦截过期或已被消费的 Token)。关键不在于“锁住整个接口”,而在于为每次合法请求绑定唯一、有时效的凭证,并用 Redis 的原子操作做“存在即通过、通过即失效”的判断。

Token 生成与下发(客户端首次获取)

用户触发需幂等的操作前(如点击“提交订单”),先调用一个专用接口(如 /api/v1/idempotent/token)获取 Token:

  • 服务端生成全局唯一字符串,推荐用 TP6 内置的 think\helper\Str::random(32) 或结合时间戳+微秒+随机数拼接,避免依赖外部 UUID 库;
  • 将 Token 作为 Key 存入 Redis,Value 可存空值或简要上下文(如用户 ID、业务类型),并设置合理 TTL(如 10 分钟);
  • 务必使用 SET key value EX seconds NX 命令(TP6 Redis 封装中对应 $redis->set($key, $value, ['ex' => 600, 'nx' => true])),确保写入原子性,防止并发生成重复 Token;
  • 响应中将 Token 放入 JSON body(如 {"token": "abc123..."}),前端需在后续业务请求中携带(建议放在请求头 X-Idempotent-Token)。

业务接口的幂等校验(带 Token 请求时)

真正执行业务的接口(如 /api/v1/order/create)需在逻辑开始前完成校验:

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载
  • 从请求头或参数中提取 Token,拼接成 Redis Key(如 idempotent:token:abc123...);
  • 用 Lua 脚本执行“判断是否存在 + 删除”两个动作,保证原子性(这是防并发重复的关键):
    -- Lua 脚本示例(保存为 resources/script/check_and_del.lua)
    if redis.call("exists", KEYS[1]) == 1 then<br>  return redis.call("del", KEYS[1])<br>else<br>  return 0<br>end
  • TP6 中调用:$result = $redis->eval($luaScript, [$tokenKey], 1);;
  • 若 $result === 1,说明 Token 有效且已成功标记为“已使用”,可继续执行下单等业务;
    若 $result === 0,直接返回 409 Conflict 或自定义错误码(如 {"code": 4001, "msg": "请求已处理,请勿重复提交"})。

集成到中间件或 AOP 风格拦截(降低侵入性)

为避免每个控制器方法都手写校验逻辑,建议封装为中间件:

  • 创建中间件 app/middleware/IdempotentCheck.php;
  • 在 handle() 中解析请求头 Token,执行上述 Lua 校验;
  • 校验失败时中断请求并返回统一错误响应,成功则 return $next($request);
  • 在路由或控制器类注解中绑定该中间件,例如:
    Route::post('order/create', 'OrderController@create')->middleware('idempotent');

注意事项与边界处理

实际落地时需关注几个易忽略点:

  • Token 失败重试机制:若业务执行中途异常(如数据库写入失败),Token 已被删除,此时前端不应直接重发原 Token。应设计“重试时重新申请新 Token”流程,或服务端在捕获异常后尝试回写 Token(需谨慎,避免状态不一致);
  • Key 命名空间隔离:不同环境(dev/test/prod)或不同业务线(支付/订单/退款)的 Token Key 应加前缀区分,如 idempotent:pay:${token},避免误删;
  • Redis 故障降级:生产环境需考虑 Redis 不可用时的兜底策略,例如记录日志告警 + 允许有限次数的重复(配合数据库唯一索引兜底),而非直接报错阻断;
  • 不适用于 GET 查询类接口:幂等校验主要针对有副作用的写操作(POST/PUT/DELETE),GET 本身语义幂等,无需额外 Token。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

redis thinkphp

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1953

5

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.07

2834

5

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3088

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4589

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3729

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

426

15

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4329

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

3835

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6992

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习