分布式锁的应用实践 | 微服务申请逐渐递增且不重复的号码

需求

用户在平台注册时,需要申请一个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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
应用场景: Redis分布式锁适用于涉及多个应用实例共享同一个资源的场景,需要协调和同步互斥访问的情况。以下是一些常见的应用场景: 1. 分布式任务调度:多个应用实例需要协调执行某个任务,使用Redis分布式锁可以确保只有一个实例获得锁,并执行任务,避免重复执行。 2. 分布式缓存更新:在缓存失效时,多个应用实例可能同时去更新缓存,使用Redis分布式锁可以确保只有一个实例获得锁,并去更新缓存,避免缓存雪崩。 3. 分布式资源竞争:多个应用实例竞争同一个资源,如数据库连接、文件访问等,使用Redis分布式锁可以确保只有一个实例获得锁,并进行资源访问。 4. 分布式限流:在高并发场景下,为了控制请求的并发量,可以使用Redis分布式锁实现限流,只有获取到锁的请求才能继续执行,其他请求则需要等待。 总之,Redis分布式锁可以在需要协调和同步多个应用实例之间的访问的场景下发挥作用,确保数据一致性和可靠性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Redis 分布式锁实现原理和应用场景](https://blog.csdn.net/weixin_43025343/article/details/131081958)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值