分布式任务锁

分布式任务锁:Redis 实现,获取锁/释放锁,防止订单重复扣款与消息重复发送

分布式任务锁:传入锁 key,获取锁、释放锁;防止重复执行任务。
基于 Redis SET NX 实现,多台服务器共用同一把锁。

典型场景:订单防重复扣款、消息防重复发送、定时任务防并发执行。
获取锁成功返回 token,业务完成后须用同一 token 释放锁。

调用地址:https://api.ynlskj.com.cn/gateway/distlock

请求方法:POST

在其他地方怎么调用

  1. 请求地址用上面的调用地址,把 JSON 放在请求体里
  2. 方法用 POST
  3. API Key 只能放在请求头 X-API-Key,不要写进网址,也不要写进 Query 框
  4. Key 在「个人中心 → API Key」里复制,登录后会自动填入你自己的 Key

参数说明

参数位置必填说明
keyBody JSON锁标识,如 order:pay:123msg:notify:456
actionBody JSONacquire 获取锁(默认)、release 释放锁、extend 续期、status 查询是否被占用
ttlBody JSON锁过期秒数,默认 30,最大 86400。获取锁与续期时使用
tokenBody JSON释放/续期时必填获取锁成功时返回的凭证,防止误释放别人的锁
namespaceBody JSON命名空间,用于同一账号下隔离不同业务线
X-API-KeyHeader你的 API Key

这个接口是干什么的?

把「分布式锁」做成远程 API。业务在执行关键操作之前先调本接口尝试获取锁,只有 acquired=true 才继续执行;完成后用返回的 token 释放锁,避免同一订单重复扣款、消息重复发送、定时任务并发跑两次。

适合小微团队不想自建 Redis 锁代码:支付回调、消息通知、库存扣减、对账脚本等,都可以远程调一次完成加锁判断。

典型使用流程

  1. 收到业务请求(如支付成功回调、待发送通知)
  2. 先调本接口key=order:pay:订单号ttl=30
  3. 看返回acquired=true 且记下 token,再执行业务;false 则说明已有实例在处理,直接跳过
  4. 业务结束:调 action=release 带上同一 keytoken 释放锁

适用场景

场景key 示例建议 ttl
订单防重复扣款order:pay:2024082300130–60 秒
消息防重复发送msg:notify:用户ID60 秒
定时任务防并发job:daily_report300 秒
库存扣减stock:sku_100110–30 秒
对账 / 导出脚本export:merchant_5600 秒

请求示例

场景Body 示例
获取锁{"action":"acquire","key":"order:pay:10086","ttl":30}
释放锁{"action":"release","key":"order:pay:10086","token":"返回的token"}
续期(长任务){"action":"extend","key":"job:daily_report","token":"...","ttl":120}
查询是否被占用{"action":"status","key":"order:pay:10086"}

业务侧代码示例(伪代码)

resp = POST /gateway/distlock {"action":"acquire","key":"order:pay:"+orderId,"ttl":30}
if (!resp.data.acquired) {
  return "已有实例在处理,跳过"
}
token = resp.data.token
try {
  // 执行业务:扣款、发消息等
} finally {
  POST /gateway/distlock {"action":"release","key":"order:pay:"+orderId,"token":token}
}

说明与限制

  • 基于 Redis SET NX + Lua 安全释放,多台服务器共用同一把锁
  • 锁带 ttl 自动过期,防止进程崩溃导致死锁;长任务请用 extend 续期
  • 释放锁必须携带获取时返回的 token,不能释放他人持有的锁
  • 每个 API Key 账号下的 key 相互隔离;可用 namespace 再分子业务

返回说明

字段说明
retok 成功,err 失败
data.acquired核心字段:获取锁时 true 表示成功,false 表示锁已被占用
data.token获取锁成功时的凭证,释放/续期时必须原样传回
data.released释放锁是否成功(token 不匹配时为 false)
data.extended续期是否成功
data.held查询状态时:锁是否被占用
data.ttl / expire_at剩余秒数 / 过期 Unix 时间戳
data.retry_after获取锁失败时,建议等待秒数(等于当前锁剩余 ttl)
msg本站提示,如「次数充足,剩余 99 次」或「次数不足,剩余 0 次」
remain_quota本次调用后的剩余次数

可直接复制的代码

未登录时示例只显示「你的密钥」。登录后会自动填入你自己的 Key,不会展示别人的。

<?php
$ch = curl_init('https://api.ynlskj.com.cn/gateway/distlock');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => ['X-API-Key: 你的密钥', 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS => '{
    "action": "acquire",
    "key": "order:pay:10086",
    "ttl": 30
}',
]);
echo curl_exec($ch);

请求参数演示

{"action":"acquire","key":"order:pay:10086","ttl":30}

响应演示

{"ret":"ok","data":{"action":"acquire","key":"order:pay:10086","acquired":true,"token":"a1b2c3d4e5f6789012345678abcdef01","ttl":30,"expire_at":1735689630}}

在线调试

登录后可在线调试。调试会真实调用网关并消耗次数。

去登录