springboot - 2.7.3版本 - (四)整合Redisson

一,关于Redisson

Jedis 和 lettuce 是比较纯粹的 Redis 客户端,几乎没提供什么高级功能。Redisson 的优势是提供了很多开箱即用的 Redis 高级功能,很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列等。

二,在项目中的使用

1)pom.xml中添加依赖包

<!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
<dependency>
	<groupId>org.redisson</groupId>
	<artifactId>redisson-spring-boot-starter</artifactId>
	<version>3.17.6</version>
</dependency>

2)在配置文件application.yml中通过spring.redis.redisson.file 来指定redisson的配置文件名称

# =======================================================================
redisson:
      file: classpath:redisson.yml
# =======================================================================

添加redisson.yml配置,参考文档:2. 配置方法 · redisson/redisson Wiki · GitHub

# 单节点配置
singleServerConfig:
  # 节点地址
  address: redis://127.0.0.1:6379
  # 密码
  password: 
  # 客户端名称
  clientName: 
  # 数据库编号,选择使用哪个数据库0~15
  database: 6
  # 连接空闲超时,单位:毫秒
  idleConnectionTimeout: 10000
  # 连接超时,单位:毫秒
  connectTimeout: 10000
  # 命令等待超时,单位:毫秒
  timeout: 3000
  # 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。
  # 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
  retryAttempts: 3
  # 命令重试发送时间间隔,单位:毫秒
  retryInterval: 1500
  # 单个连接最大订阅数量
  subscriptionsPerConnection: 5
  # 发布和订阅连接的最小空闲连接数
  subscriptionConnectionMinimumIdleSize: 1
  # 发布和订阅连接池大小
  subscriptionConnectionPoolSize: 50
  # 最小空闲连接数
  connectionMinimumIdleSize: 32
  # 连接池大小
  connectionPoolSize: 64
  # DNS监测时间间隔,单位:毫秒
  dnsMonitoringInterval: 5000

#=================================================================================
# 线程池数量,默认值: 当前处理核数量 * 2
threads: 0
# Netty线程池数量,默认值: 当前处理核数量 * 2
nettyThreads: 0
# 编码
codec: 
  class: org.redisson.codec.JsonJacksonCodec
# 传输模式
transportMode : "NIO"

3)自定义redisson配置类

package com.qi.study.springboot.config;

import java.io.IOException;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfiguation {

	@Bean
    public RedissonClient redisson() throws IOException {
        // 本例子使用的是yaml格式的配置文件,读取使用Config.fromYAML,如果是Json文件,则使用Config.fromJSON
        Config config = Config.fromYAML(RedissonConfiguation.class.getClassLoader().getResource("redisson.yml"));
        return Redisson.create(config);
    }
}

4)编写redisson操作工具类-这里主要是分布式锁的使用

package com.qi.study.springboot.util;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class RedissonUtil {

	private final static Logger LOGGER = LoggerFactory.getLogger(RedissonUtil.class);

	private RedissonClient redissonClient;
	
	@Autowired
	public void setRedisson(RedissonClient redisson) {
        this.redissonClient = redisson;
    }

	/**
     * 加锁
     * @param lockKey
     * @return
     */
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        LOGGER.info("RedissonUtil加锁成功,Redis Lock key :{}", lockKey);
        return lock;
    }
 
    /**
     * 带超时的锁
     * @param lockKey
     * @param timeout 超时时间 单位:秒
     */
    public RLock lock(String lockKey, int timeout) {
        return lock(lockKey, timeout, TimeUnit.SECONDS);
    }
 
    /**
     * 带超时的锁
     * @param lockKey
     * @param timeout 超时时间
     * @param unit 时间单位
     */
    public RLock lock(String lockKey, int timeout, TimeUnit unit ) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        LOGGER.info("RedissonUtil加锁成功,Redis Lock key :{}", lockKey);
        return lock;
    }
 
 
    /**
     * 尝试获取锁
     * @param lockKey
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * 默认时间单位:秒
     * @return
     */
    public  boolean tryLock(String lockKey, int waitTime, int leaseTime) {
        return tryLock(lockKey, waitTime, leaseTime, TimeUnit.SECONDS);
    }
 
    /**
     * 尝试获取锁
     * @param lockKey
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @param unit 时间单位
     * @return
     */
    public boolean tryLock(String lockKey, int waitTime, int leaseTime, TimeUnit unit) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }
 
    /**
     * 释放锁
     * @param lockKey
     */
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        // 释放锁,判断要解锁的key是否已被锁定并且是否被当前线程保持
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
            LOGGER.info("RedissonUtil释放锁成功,Redis Lock key :{}", lockKey);
        }
    }
}

三,添加测试代码

    @RequestMapping("/redis/setLock")  
    public JsonResult setLock(@RequestParam(name="lockKey") String lockKey){
    	redissonUtil.lock(lockKey);
        return JsonResultBuilder.ok();
    }
    
    @RequestMapping("/redis/pushLock")  
    public JsonResult pushLock(@RequestParam(name="lockKey") String lockKey){
    	redissonUtil.unlock(lockKey);
    	return JsonResultBuilder.ok();
    }

四,报错说明:

该篇是基于上一篇整合swagger3之后的项目添加的,发现添加redisson包之后启动会报错,解决办法是在SwaggerConfiguration.java配置类中添加如下代码:

    @Bean
	public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
	    return new BeanPostProcessor() {

	        @Override
	        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	            if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
	                customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
	            }
	            return bean;
	        }

	        private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
	            List<T> copy = mappings.stream()
	                    .filter(mapping -> mapping.getPatternParser() == null)
	                    .collect(Collectors.toList());
	            mappings.clear();
	            mappings.addAll(copy);
	        }

	        @SuppressWarnings("unchecked")
	        private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
	            try {
	                Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
	                field.setAccessible(true);
	                return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
	            } catch (IllegalArgumentException | IllegalAccessException e) {
	                throw new IllegalStateException(e);
	            }
	        }
	    };
	}

五,启动测试

上面我们配置的database=6,请求发送后通过redis 连接工具查看:

 

六,源代码下载:https://download.csdn.net/download/MyNoteBlog/86661443

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值