当前位置:网站首页>分布式锁的应用实践 | 微服务申请逐渐递增且不重复的号码
分布式锁的应用实践 | 微服务申请逐渐递增且不重复的号码
2022-08-06 12:19:00 【魏云舒】
需求
用户在平台注册时,需要申请一个sip号,由固定部分 + 变化部分组成,其中变化的部分是从1000001开始,逐渐递增的,每申请一个,则加1。采用微服务的部署方式,能够从微服务集群中不冲突的获取号码。
方案设计

- 在单个服务内,通过synchronized防止多个线程抢一个资源,实现数据的一致性
- 在微服务集群中,通过分布式锁,防止多个服务抢同一个资源,实现分布式服务数据的一致性
- 这里采用redis分布式锁实现,实现如下:
- SETNX key val:仅当key不存在时,设置一个 key 为 value 的字符串,返回1;若 key 存在,设置失败,返回 0;
- Expire key timeout:为 key 设置一个超时时间,以 second 秒为单位,超过这个时间锁会自动释放,避免死锁;
- DEL key:删除 key。
代码实现
private static final String NUM_LOCK_KEY = "NUM_LOCK";
private static final Long NUM_LOCK_EXPIRE = 500;
private static final Long MAX_NUMBER_INDEX = 1;
// 获取一个当前可用号码
private synchronized String getMaxValue() {
// 获取号码锁,防止并发导致数据异常
String lockKey = NUM_LOCK_KEY;
RedisAtomicLong counter = new RedisAtomicLong(lockKey, redis.getConnectionFactory());
Long lockValue = counter.incrementAndGet();
// 如果其他线程调用,则等待重试,直到5次结束
int count = 0;
while (lockValue > 0 && count < 5) {
try {
Thread.sleep(NUM_LOCK_EXPIRE);
} catch (InterruptedException e) {
log.error("线程休眠异常, {}", e);
}
lockValue = counter.incrementAndGet();
count++;
}
if (lockValue > 0) {
log.info("获取号码锁失败");
return null;
} else {
// 获得锁的线程设置锁的有效期,防止永久上锁
redis.expire(lockKey, configValue.getSipNumLockExpire(), TimeUnit.MILLISECONDS);
}
Map<String, Object> queryMap = new HashMap<>();
queryMap.put("id", MAX_NUMBER_INDEX);
MaxNo maxNo = maxNoDao.selectOneByMap(queryMap);
long result = maxNoDao.update(maxNo);
if (result == 0) {
log.info("更新号码失败");
return null;
}
// 释放号码锁
redis.delete(lockKey);
return maxNo.getMaxValue().toString();
}
边栏推荐
- 完美数列 PAT B1030
- Nacos启动失败:Nacos Server did not start because dumpservice bean construction failure:No DataSource set
- CISP-PTE Practical Exercises Explained II (New Edition)
- Microsoft's new service allows businesses to expand access to their threat intelligence repository
- 公司系统太多,如何实现账号互通?
- 零数科技携文化和旅游部艺术发展中心发布“文化艺术链”
- 一个国内的占位图服务
- 【SSL集训DAY1】C【暴力】【数学】
- Exchange Comprehensive Experiment
- Absolutely!Ali people explain tens of billions of high-concurrency systems in 7 parts (full-color booklet open source)
猜你喜欢

NC1 Addition of Large Numbers

Draw timing diagrams with code!YYDS

CISP-PTE Practical Exercises Explained II (New Edition)

Flexible and easy-to-use sql monitoring script part4

链表 | 找出并返回链表相交的起始节点 | leecode刷题笔记

【SSL集训DAY1】B【动态规划】

SQL图解面试题:如何找到喜欢的电影?(表连接,语句执行顺序、模糊查询)

CISP-PTE Practical Exercises Explanation One (New Version)

SQL图解面试题:人均付费如何分析?(分组、条件汇总)

高性能云原生数据对象存储MinIO实战-上
随机推荐
纯色山鹪莺
如何用 ONES 管理工单,快速响应用户反馈?|2分钟了解 ONES
【SQL刷题】Day2----SQL语法基础查询
SQL图解面试题:如何实现精细化运营?(具体且精确的全过程详细讲解)
stp simple configuration
你对数据库与数据处理了解吗?
A domestic placeholder service
剧照怎么找?哪里获取高清资源?这9个网站渠道相见恨晚! 原创
SQL 注入复习总结
哈希表 | 快乐数 | leecode刷题笔记
Kubernetes stain and tolerance
半年总结以及状态调整
顶象首期业务安全月报来了!
Apscheduler定时任务
链路聚合简述
关机程序
Disadvantages of Kubernetes Virtual Machine Deployment
Istio的扩展和定制
Kubernetes 怎么优雅升级
VS Code 代码提示快捷键