分布式锁实战

背景

柯苏远写于2024年4月7日 20点10分

公司的主要业务线是国外电商,之前是在客户下订单,以及厂商对客户订单进行打包发货等关键节点都会给客户发送对应邮件。

可是由于邮件没有短信那么及时,方便,为了提高客户的体验和下单率准备在整个系统接入短信。

所以这里就涉及到要和国外通讯商对接短信发送的接口。

这里主要是两个接口:一个是获取token接口,一个是发送短信接口。获取token的接口一个小时之内只能获取5次,一次获取到的token有效期是一个小时。

简单 token 缓存设计

根据背景描述,显而易见的是,token必须要缓存起来,因为一个小时就只能获取5次,所以必须尽量重复使用,以下是我的设想的接口调用情况:

从直观感受上来讲,确实是可以了,我们通常的设计一般情况下都不会考虑多线程并发的情况。

但是!!! 我们的业务项目是电商欸,肯定会存在并发的可能。

所以我将方案给我老大看了之后,我老大一眼就看出我没有考虑并发问题,要我重新去设计。

并发 token 缓存设计

由于上一版的核心就是没考虑并发,如果此时100个线程同时去缓存获取并且同时没获取到,再然后同时去调用了短信的api,那么这个api一分钟5次的限制一下子就到了峰值。

考虑到并发点,我引入了分布式锁,对之前方案做了更新,如下图所示:

整个流程图看起来复杂了很多,其实和上面方案比较起来主要就两点:

  1. 在调用api之前加了分布式锁,在取得token之后,释放分布式锁。
  2. 如果在一个线程持有分布式锁的情况,其它线程进来没获取锁,就让它们冷处理,类似一个while循环操作,然后睡眠200毫秒,循环15次去缓存里取。如果15次都没有从缓存里取到token对象,那么就要进行去抢夺分布式锁,如果抢夺成功那么执行调用api流程,如果失败,那么再去缓存看看,有的话直接返回token对象,没有的话再去抢夺分布式锁。

具体实现 & 当前问题

具体实现分布式锁:

  • 在项目里用的是redisTemplate,有一个setIfAbsent,然后再结合expire(项目里是10s),用这两个命令来获取分布式锁。
  • 释放的时候直接就是delete。

其实这种实现方式是不严谨的,有如下缺点:

  • setIfAbsent和expire:这两个不是原子命令,如果setIfAbsent成功,由于某种原因expire没有成功,那么就会造成死锁,这个分布式锁会得不到释放。
  • expire 这里设置的过期时间是10s,但是如果我业务执行时间大于10s呢?分布式锁就失效了,那还搞个毛线?其它线程也进我的临界区了,线程不安全了。
  • delete是直接删除的,没有考虑某种未知错误造成删除失败的原因。这个其实是小问题,即使删除失败也有超时的保证。

这三个目前存在的问题和老大聊了,老大说确实是有这问题,然后后面研究一下redisson,然后完善一下这个分布式锁,后面等手头活少点去研究一下。

总结

  1. api token 缓存设计

  2. 多线程下 api token 缓存设计

  3. 分布式锁的实现 & 目前存在的问题

  4. 后续目标:研究redisson实现分布式锁。

相关推荐
LHICOD4 小时前
Linux-2
java·linux·后端·jar·vmware·svm·vm
小杨互联网4 小时前
Go 现代 CLI 工具离线镜像合集
开发语言·后端·golang·开源·go·命令行
lazy H4 小时前
【计算机网络】第 15 篇:Java BIO、NIO 与高并发网络通信——从 Socket 理解 I/O 模型
网络·后端·tcp/ip·计算机网络·nio·408
geovindu4 小时前
rust: Semaphore Pattern
开发语言·后端·设计模式·rust·代理模式·企业级信号量模式·同步型模式
Thneonl6 小时前
Claude Code 频繁 Compacting?发布次日我根治了 2 个痛点
后端·rust
LV技术派7 小时前
【成为 AI Native Builder · 02】什么是 AI Native Builder:一个人 + AI,交付完整闭环
前端·程序员·ai编程
环境栈笔记7 小时前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
小小张说故事8 小时前
Python 的 list 为什么能装下任何类型?拆开 PyObject* 数组,以及它让你多付了多少内存
后端·python
小蒜学长8 小时前
基于SpringBoot 框架的自媒体新闻系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·mysql数据库·自媒体新闻管理系统
IT_陈寒9 小时前
JavaScript实战技巧总结:深挖数组遍历的性能陷阱与实战解法
前端·人工智能·后端