zoukankan      html  css  js  c++  java
  • SpringBoot_集成Redis

    Spring boot 集成 Redis 的步骤如下:

    1、在pom.xml中配置相关的jar依赖:

    <!-- 加载spring boot redis包 -->
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    2、在Springboot核心配置文件application.properties中配置redis连接信息:

    spring.redis.host=192.168.230.128
    spring.redis.port=6379
    spring.redis.password=123456

    3、 配置了上面的步骤,Spring boot将自动配置RedisTemplate,在需要操作redis的类中注入redisTemplate:

    redis操作的实体类必须实现序列化接口

     

    成功后发现存入redis的key有一些特殊的编码格式,可读性不高

     

     

    spring boot帮我们注入的redisTemplate类,泛型里面只能写 <String, String>、<Object, Object>

    在高并发情况下,该方法可能会出现问题:可能没有缓存,都到数据库取查询,增加数据库服务器的压力。

    在action中模拟多线程来访问该sevice方法

    @Autowired
    private TClassService tClassService;
    
    @RequestMapping("index.do")
    public @ResponseBody Object list(){
        //模拟高并发
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                tClassService.list();
            }
        };
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i=0;i<100;i++){
            executorService.submit(runnable);
        }
        return tClassService.list();
    }

    修改service方法中的提示

    public List<TClass> list() {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
    
        //先到缓存中查询
        List<TClass> list = (List<TClass>)redisTemplate.opsForValue().get("data.class");
        //如果缓存中没有数据,就从数据库取数据
        if (list == null){
            System.out.println("查询的数据库");
            //从数据库中获取数据,查询完后将结果放入缓存
            list = classMapper.list();
            redisTemplate.opsForValue().set("data.class",list);
        }else {
            System.out.println("查询的缓存");
        }
        return list;
    }

    启动,测试结果,发下很多都是在数据库查的,而不是查询缓存

     原理:多线程同时进入方法

     解决方式一:同步方法

    在方法上夹synchronized关键字,同步方法,效率太低

    解决方式二:同步代码块

    public List<TClass> list() {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
    
        //先到缓存中查询
        List<TClass> list = (List<TClass>)redisTemplate.opsForValue().get("data.class");
        if (list == null){//如果找到了,就不加锁了,提高效率
            synchronized (this){
                list = (List<TClass>)redisTemplate.opsForValue().get("data.class");
                //如果缓存中没有数据,就从数据库取数据
                if (list == null){
                    System.out.println("查询的数据库");
                    //从数据库中获取数据,查询完后将结果放入缓存
                    list = classMapper.list();
                    redisTemplate.opsForValue().set("data.class",list);
                }else {
                    System.out.println("查询的缓存");
                }
            }
        }else{
            System.out.println("查询的缓存");
        }
        return list;
    }

    测试结果,只有第一次查询数据库,其余的都是查询缓存

     哨兵模式redis集群配置:

    #redis集群哨兵模式配置
    spring.redis.password=redis
    spring.redis.sentinel.master=mymaster
    spring.redis.sentinel.nodes=192.168.179.128:26380,192.168.179.128:26382,192.168.179.128:26384
    学习中,博客都是自己学习用的笔记,持续更新改正。。。
  • 相关阅读:
    Java数组分配内存空间
    Java中的数组
    Java中可变参数
    什么是方法的重载
    break语句与continue语句
    三大循环结构
    程序流程控制
    Java的运算符
    基本数据类型转换之向上转型和向下转换
    修改IIS虚拟目录名称
  • 原文地址:https://www.cnblogs.com/Tunan-Ki/p/11762403.html
Copyright © 2011-2022 走看看