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

猜你喜欢

转载自www.cnblogs.com/Tunan-Ki/p/11762403.html