微服务-13 SpringCloud快速集成redis缓存,Redisson分布式锁

redis缓存,Redisson分布式锁
Redis介绍:
        本文快速集成Redis缓存与Redisson分布式锁,想要让学习redis基础的同学可以去看我另一篇博客 https://www.cnblogs.com/langjunnan/p/15974106.html, 言归正转,在开发当中我们一定会去集成缓存 ,那么Redis缓存是单线程多路IO复用的,非常快,而且提供了9种数据类型,使用起来也很方便,一会我们就去整合Redis到我们的现有微服务项目当中
Redisson介绍:
       在微服务架构或集群当中,我们避免不了分布式锁的存在,单体应用我们还可以使用 syn look等java提供的锁,但是在多个服务节点中 我们又无法控制统一状态,所以我们需要分布式锁的存在,
        为什么要使用Redisson呢? 因为人家给我们集成好了分布式框架,用起来也很方便,Redisson没出现之前我们很多同学再用 redis的setNx 做分布式锁,但是运行过程中也出现了很多问题,例如  加锁后宕机突然就死锁,或者是加了超时时间后超时了,另一个线程进入后,第一个线程执行完了释放错了锁,等等种种原因都存在,但是我们使用了Redisson就不会出现这种问题,因为人家Redisson都为我们封装好了,处理好了这些问题,我们只关注怎么用分布式锁就可以了,
   
快速集成Redis    
        我们还是在原来的基础之上进行集成Redis,
第一步 添加配置redis的pom文件
        
<!-- 缓存-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
 第二步配置参数
 
#redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#redis连接密码
spring.redis.password=123456
#连接池最大连接数
spring.redis.lettuce.pool.max-active=20
#连接池最大阻塞时间
spring.redis.lettuce.pool.max-wait=-1
#连接池中最大空闲连接
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=1
## 连接超时时间(毫秒)
spring.redis.timeout=5000
 
第三步 创建程序启动加载配置类RedisTemplate,和自封装工具类,可以看到 redis文件夹下一共两个类 RedisConfig,RedisUtil

 
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
 
 
@Configuration
public class RedisConfig extends CachingConfigurerSupport{
   
   @Bean(name="redisTemplate")
   public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
      StringRedisTemplate template = new StringRedisTemplate(connectionFactory);
      
      Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
      ObjectMapper om = new ObjectMapper();
      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      jackson2JsonRedisSerializer.setObjectMapper(om);
      template.setValueSerializer(jackson2JsonRedisSerializer);
      template.afterPropertiesSet();
      System.out.println("--------------------------"+template.toString());
      return template;
   }
}
    
    copy的代码
 
 
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
 
 
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
 
 
@Component
public class RedisUtil {
 
 
   protected RedisTemplate<String, Object> redisTemplate;
 
 
   @Resource
   public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
      this.redisTemplate = redisTemplate;
   }
 
 
   /**
    * 写入缓存
    *
    * @param key
    * @param value
    * @return
    */
   public boolean set(final String key, Object value, long timeOut) {
      boolean result = false;
      try {
         ValueOperations<String, Object> operations = redisTemplate.opsForValue();
         operations.set(key, value, timeOut, TimeUnit.SECONDS);
 
 
         result = true;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return result;
   }
 
 
   /**
    * 写入缓存
    *
    * @param key
    * @param value
    * @return
    */
   public boolean set(final String key, Object value) {
      boolean result = false;
      try {
         ValueOperations<String, Object> operations = redisTemplate.opsForValue();
         operations.set(key, value);
 
 
         result = true;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return result;
   }
 
 
 
 
 
 
   /**
    * 读取缓存
    *
    * @param key
    * @return
    */
   public Object get(final String key) {
      Object result = null;
      try {
         ValueOperations<String, Object> operations = redisTemplate.opsForValue();
         if (!exists(key)) {
            return null;
         }
         result = operations.get(key);
         return result;
 
 
      } catch (Exception e) {
         e.printStackTrace();
         return null;
      }
 
 
   }
 
 
   /**
    * 删除缓存
    */
   public void remove(final String key) {
      redisTemplate.delete(key);
 
 
   }
 
 
   public boolean exists(String key) {
 
 
      return redisTemplate.hasKey(key);
   }
 
 
   public  Long createIncrement(String key,int value){
      ValueOperations<String, Object> operations = redisTemplate.opsForValue();
      return operations.increment(key, value);
   }
 
 
 
 
   public void expire(String key,int coloseSeconds){
 
 
      redisTemplate.expire(key,coloseSeconds,TimeUnit.SECONDS);
   }
   /*添加当天新增用户数量*/
   public void newIncrement() {
      ValueOperations<String, Object> operations = redisTemplate.opsForValue();
      operations.increment("new", 1);
   }
   /*添加当天活跃用户数量*/
   public void activeIncrement() {
      ValueOperations<String, Object> operations = redisTemplate.opsForValue();
      operations.increment("active", 1);
   }
   /*获取当天新增用户数量*/
   public Integer getNewCount() {
      return Integer.valueOf(redisTemplate.boundValueOps("new").get(0, -1));
   }
   /*获取当天活跃用户数量*/
   public Integer getActiveCount() {
      
      return Integer.valueOf(redisTemplate.boundValueOps("active").get(0, -1));
 
 
   }
}
第四步: 测试  首先我们放入缓存 紧接着又从缓冲拿出测试

 
 
 
 
import com.nacos.redis.RedisUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
 
import javax.annotation.Resource;
 
 
@RestController
public class RedisTestController {
 
 
    @Resource
    RedisUtil redisUtil;
 
 
    @RequestMapping("getTestRedis")
    public  Object get(String value){
            redisUtil.set("name",value);
          return   redisUtil.get("name");
    }
}
结果:

 
 
快速集成Redisson
第一步 添加配置redis的pom文件
 
<!-- redisson -->
<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson-spring-boot-starter</artifactId>
   <version>3.9.1</version>
   <exclusions>
      <exclusion>
         <groupId>org.redisson</groupId>
         <artifactId>redisson-spring-data-23</artifactId>
      </exclusion>
   </exclusions>
</dependency>
第二步: 配置文件

 

 

 
#redisson peizhi
redisson.address = redis://61.171.3.140:6379
redisson.database = 10
 
第三步: 配合类   redisson 目录下的了都是相关的类, 请自行下载上面的源码查看
 
 
 
第四步:测试

测试代码:
 
 
 
import com.nacos.redis.RedisUtil;
import com.nacos.redisson.RedissLockUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
 
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
 
 
@RestController
public class RedissonTestController {
 
 
 
 
    @RequestMapping("testRedissonRedis")
    public  void test(String value){
        for (;true;){
            new Thread(()->{
                // lockKey 锁的名称
                // 获取锁等待的waitTime秒时间
                // leaseTime秒 后锁自动释放  为了避免本地服务宕机后 锁无法释放问题 (为了避免业务逻辑在指定时间内运行不完而延长锁的时间,消耗性能较大,建议给定足够的时间)跑完业务逻辑代码
                // TimeUnit.SECONDS  waitTime參數与leaseTime单位
                boolean flag= RedissLockUtil.tryLock("token", TimeUnit.SECONDS,2,30);
                System.out.println("当前线程名称 "+Thread.currentThread().getName()+" \t 是否获取到锁 "+flag);
                if(flag){
                    //获取到锁之后 执行的业务逻辑代码
                    try {
                        Thread.sleep(5000);
                        //执行业务逻辑任务10s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        //解锁
                        System.out.println("当前线程名称 "+Thread.currentThread().getName()+" \t 释放锁 "+flag);
                        RedissLockUtil.unlock("token");
                    }
                }else{
                    System.out.println("获取锁失败 当前业务任务 请等待");
                }
            }).start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
 
posted @ 2022-03-07 00:07  郎小乐  阅读(1282)  评论(0)    收藏  举报