• 分布式缓存


    本地缓存问题:每个微服务都要有缓存服务、数据更新时只更新自己的缓存,造成缓存数据不一致

    解决方案:分布式缓存,微服务共用 缓存中间件

    分布式锁
    分布式项目时,但本地锁只能锁住当前服务,需要分布式锁

    redis分布式锁的原理:setnx,同一时刻只能设置成功一个

    前提,锁的key是一定的,value可以变

    没获取到锁阻塞或者sleep一会

    设置好了锁,玩意服务出现宕机,没有执行删除锁逻辑,这就造成了死锁

    解决:设置过期时间
    业务还没执行完锁就过期了,别人拿到锁,自己执行完去删了别人的锁

    解决:锁续期(redisson有看门狗),。删锁的时候明确是自己的锁。如uuid
    判断uuid对了,但是将要删除的时候锁过期了,别人设置了新值,那删除了别人的锁

    解决:删除锁必须保证原子性(保证判断和删锁是原子的)。使用redis+Lua脚本完成,脚本是原子的

    if redis.call("get",KEYS[1]) == ARGV[1] 
    then
    	return redis.call("del",KEYS[1])
    else
        return 0
    end;
    

      

    stringRedisTemplate.execute(
        new DefaultRedisScript<Long返回值类型>(script脚本支付非常, Long.class返回值类型), 
        Arrays.asList("lock")键key的集合, 
        lockValue);
    

      

    http://redis.cn/commands/set.html

    最终代码:

    public Map<String, List<Catalog2Vo>> getCatalogJsonDbWithRedisLock() {
        String uuid = UUID.randomUUID().toString();
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        Boolean lock = ops.setIfAbsent("lock", uuid,500, TimeUnit.SECONDS);
        if (lock) {
            Map<String, List<Catalog2Vo>> categoriesDb = getCategoryMap();
            String lockValue = ops.get("lock");
            String script = "if redis.call("get",KEYS[1]) == ARGV[1] then
    " +
                "    return redis.call("del",KEYS[1])
    " +
                "else
    " +
                "    return 0
    " +
                "end";
            stringRedisTemplate.execute(
                new DefaultRedisScript<Long>(script, Long.class),
                Arrays.asList("lock"),
                lockValue);
            return categoriesDb;
        }else {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 睡眠0.1s后,重新调用//自旋
            return getCatalogJsonDbWithRedisLock();
        }
    }
    ————————————————
    

      

  • 相关阅读:
    spring学习笔记__spring的单例多例模式
    spring学习笔记_spring入门
    Lambda表达式
    反射
    fatal error: call to undefined function imagettftext
    阿里云 centos 安装apache和php
    php 使用 极光推送 类
    php socket解决方案
    身份证号码 15位和18位 验证
    php memcache扩展 出现错误dyld: Symbol not found: _mmc_queue_free
  • 原文地址:https://www.cnblogs.com/vincentmax/p/14480496.html
Copyright © 2020-2023  润新知