文章目录
- 前言
 - 1、分布式情况下如何加锁
 - 2、具体实现过程
 - 3、测试
 - 3.1 一个服务按照多个端口同时启动
 - 3.2 使用jmeter进行压测
 
 
前言
上一篇实现了单体应用下如何上锁,这一篇主要说明如何在分布式场景下上锁
上一篇地址:加锁
1、分布式情况下如何加锁
需要注意的点是: 在上锁和释放锁的过程中要保证原子性操作


2、具体实现过程
核心是上锁和解锁的过程
关于解锁使用脚本参考:SET key value [EX seconds] [PX milliseconds] [NX|XX]
//上锁过程
String uuid = UUID.randomUUID().toString();
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
//解锁过程、需要 调用脚本
String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then  return redis.call(\"del\",KEYS[1]) else return 0 end";
Long lock1 = (Long) redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);
         
 
    public Map<String, List<Catalog2Vo>> getCatalogJsonDbWithSpringCache() {
        //占分布式锁.redis中占坑
        String uuid = UUID.randomUUID().toString();
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
        Map<String, List<Catalog2Vo>> dataFromDb;
        if (lock) {
            System.out.println("加锁成功......");
            try {
                //加锁成功...执行业务
                dataFromDb = getCategoriesDb();
            } finally {
                //删除锁
                String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then  return redis.call(\"del\",KEYS[1]) else return 0 end";
                Long lock1 = (Long) redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);
            }
            return dataFromDb;
        } else {
            //加锁失败...重试.synchronized  休眠100ms重试
            System.out.println("加锁失败......");
            try {
                Thread.sleep(200);
            } catch (Exception e) {
            }
            //自旋方式
            return getCatalogJsonDbWithSpringCache();
        }
    }
 
3、测试
3.1 一个服务按照多个端口同时启动
模拟分布式情况、将一个服务按照多个端口同时启动
具体过程
-  
1 首先,点击修改运行配置

 -  
2 将你的项目配置的右上角的Allowl parallel run勾上(允许多启动)

 -  
3 将你的项目配置复制一份重启个名字,添加上
-Dserver.port=端口号

 

- 4 启动项目

 
3.2 使用jmeter进行压测
请求的基本配置

测试情况
 模拟的基本前提: redis中没有缓存数据
上锁成功的情况下、 三个服务中只会出现一次查询数据库、其余接口请求从redis中拿取数据.
下方是测试截图、符合预期情况 、上锁成功

 
 
redis中缓存的数据
 



















