前言

 记录项目集成redisson

项目环境

springboot 2.7.5

jdk17

操作

pom.xml

<!-- Redisson -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <scope>compile</scope>
    <version>3.11.1</version>
</dependency>

 yml配置

spring:
  redis:
    host: 127.0.0.1 # Redis服务器地址
    database: 4 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password:   # Redis服务器连接密码(默认为空)
    timeout: 5000 # 连接超时时间(毫秒)
    lettuce:
      # 连接池最大阻塞等待时间(毫秒)
      shutdown-timeout: 10000
      pool:
        # 连接池中的最小空闲连接
        min-idle: 50
        # 连接池中的最大空闲连接
        max-idle: 100
        # 连接池的最大数据库连接数
        max-active: 3000
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 300000
RedissonConfig

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Redisson配置类
 *
 * @author Xx
 * @since 2024/10/28 11:12
 */
@Configuration
public class RedissonConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private String port;

    @Value("${spring.redis.password}")
    private String password;

    /** 默认使用0号数据库 */
    @Value("${spring.redis.database:0}")
    private int database;

    @Bean
    public RedissonClient redisson() {
        Config config = new Config();
        // 配置线程池
        // 线程池数量,0=默认值: 当前处理核数量 * 2
        config.setThreads(0)
                // Netty线程池数量,0=默认值: 当前处理核数量 * 2
                .setNettyThreads(0)
                // 设置对象编码器,默认使用JsonJacksonCodec
                .setCodec(new JsonJacksonCodec())
                // 传输模式,默认NIO
                .setTransportMode(TransportMode.NIO);

        // 单节点配置
        config.useSingleServer()
                // 节点地址
                .setAddress("redis://" + host + ":" + port)
                // Redis认证密码
                .setPassword(password)
                // 客户端名称
                .setClientName("making_friends")
                // 数据库编号
                .setDatabase(database)

                // ==== 连接配置 ====
                // 连接空闲超时时间,单位:毫秒
                .setIdleConnectionTimeout(10000)
                // 连接超时时间,单位:毫秒
                .setConnectTimeout(10000)
                // 命令等待超时时间,单位:毫秒
                .setTimeout(3000)
                // 命令失败重试次数
                // 如果尝试达到 retryAttempts 仍然不能将命令发送至某个指定的节点时,将抛出错误
                // 如果尝试在此限制之内发送成功,则开始启用 timeout 计时
                .setRetryAttempts(3)
                // 命令重试发送时间间隔,单位:毫秒
                .setRetryInterval(1500)

                // ==== 订阅配置 ====
                // 单个连接最大订阅数量
                .setSubscriptionsPerConnection(10)
                // 发布和订阅连接的最小空闲连接数
                .setSubscriptionConnectionMinimumIdleSize(5)
                // 发布和订阅连接池大小
                .setSubscriptionConnectionPoolSize(50)

                // ==== 连接池配置 ====
                // 最小空闲连接数
                .setConnectionMinimumIdleSize(32)
                // 连接池大小
                .setConnectionPoolSize(64)

                // ==== DNS监控 ====
                // DNS变化扫描间隔,单位:毫秒
                .setDnsMonitoringInterval(5000);

        // 创建并返回RedissonClient实例
        return Redisson.create(config);
    }
}

RedissonUtils

import java.util.Collection;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBatch;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RSemaphore;
import org.redisson.api.RSet;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

/**
 * Redisson 工具类
 * com.macro.mall.common.util.RedissonUtils
 * @author Xx
 * dateTime 2024/10/28 11:20
 */

@Slf4j
@Component
public class RedissonUtils {

    @Resource
    private RedissonClient redissonClient;

    // ================ 通用操作 ================

    /**
     * 删除key
     */
    public void del(String key) {
        redissonClient.getBucket(key).delete();
    }
    /**
     * 删除key
     */
    public void delete(String key) {
        redissonClient.getBucket(key).delete();
    }
    /**
     * 批量删除key
     */
    public void delete(Collection<String> keys) {
        RBatch batch = redissonClient.createBatch();
        keys.forEach(key -> batch.getBucket(key).deleteAsync());
        batch.execute();
    }

    /**
     * 检查key是否存在
     */
    public boolean hasKey(String key) {
        return redissonClient.getBucket(key).isExists();
    }

    /**
     * 设置过期时间
     */
    public boolean expire(String key, long timeout, TimeUnit unit) {
        return redissonClient.getBucket(key).expire(timeout, unit);
    }

    /**
     * 获取过期时间
     */
    public long getExpire(String key, TimeUnit unit) {
        return redissonClient.getBucket(key).remainTimeToLive();
    }

    // ================ 对象操作 ================

    /**
     * 设置对象
     */
    public <T> void set(String key, T value) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.set(value);
    }

    /**
     * 设置对象带过期时间
     */
    public <T> void set(String key, T value, long timeout, TimeUnit unit) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.set(value, timeout, unit);
    }

    /**
     * 获取对象
     */
    public <T> T get(String key) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }

    // ================ 原子操作 ================

    /**
     * 原子递增
     */
    public long incr(String key, long delta) {
        return redissonClient.getAtomicLong(key).addAndGet(delta);
    }

    /**
     * 原子递减
     */
    public long decr(String key, long delta) {
        return redissonClient.getAtomicLong(key).addAndGet(-delta);
    }

    // ================ 分布式锁 ================

    /**
     * 获取可重入锁
     */
    public RLock getLock(String key) {
        return redissonClient.getLock(key);
    }

    /**
     * 获取公平锁
     */
    public RLock getFairLock(String key) {
        return redissonClient.getFairLock(key);
    }

    /**
     * 获取读写锁
     */
    public RReadWriteLock getReadWriteLock(String key) {
        return redissonClient.getReadWriteLock(key);
    }

    /**
     * 获取信号量
     */
    public RSemaphore getSemaphore(String key) {
        return redissonClient.getSemaphore(key);
    }

    // ================ 集合操作 ================

    /**
     * 获取列表
     */
    public <T> RList<T> getList(String key) {
        return redissonClient.getList(key);
    }

    /**
     * 获取集合
     */
    public <T> RSet<T> getSet(String key) {
        return redissonClient.getSet(key);
    }

    /**
     * 获取有序集合
     */
    public <T> RScoredSortedSet<T> getSortedSet(String key) {
        return redissonClient.getScoredSortedSet(key);
    }

    /**
     * 获取映射
     */
    public <K, V> RMap<K, V> getMap(String key) {
        return redissonClient.getMap(key);
    }

    // ================ 限流器 ================

    /**
     * 获取限流器
     */
    public RRateLimiter getRateLimiter(String key) {
        return redissonClient.getRateLimiter(key);
    }

    /**
     * 创建限流器
     *
     * @param key          限流器key
     * @param rate        每秒允许的请求数
     * @param rateInterval 时间间隔,默认1秒
     */
    public RRateLimiter createRateLimiter(String key, long rate, long rateInterval) {
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
        rateLimiter.trySetRate(RateType.OVERALL, rate, rateInterval, RateIntervalUnit.SECONDS);
        return rateLimiter;
    }

    // ================ 布隆过滤器 ================

    /**
     * 获取布隆过滤器
     */
    public <T> RBloomFilter<T> getBloomFilter(String key) {
        return redissonClient.getBloomFilter(key);
    }

    /**
     * 创建布隆过滤器
     *
     * @param key              布隆过滤器key
     * @param expectedInsertions 预期插入数量
     * @param falseProbability   误判率
     */
    public <T> RBloomFilter<T> createBloomFilter(String key, long expectedInsertions, double falseProbability) {
        RBloomFilter<T> bloomFilter = redissonClient.getBloomFilter(key);
        bloomFilter.tryInit(expectedInsertions, falseProbability);
        return bloomFilter;
    }

    // ================ 使用示例 ================

    /**
     * 分布式锁示例
     */
    public void lockExample() {
        RLock lock = getLock("myLock");
        try {
            // 尝试加锁,最多等待100秒,上锁10秒后自动解锁
            if (lock.tryLock(100, 10, TimeUnit.SECONDS)) {
                try {
                    // 业务逻辑
                } finally {
                    lock.unlock();
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("获取锁异常", e);
        }
    }

    /**
     * 限流器示例
     */
    public boolean rateLimitExample() {
        RRateLimiter rateLimiter = createRateLimiter("myRateLimiter", 10, 1);
        // 尝试获取一个令牌
        return rateLimiter.tryAcquire(1);
    }

    /**
     * 布隆过滤器示例
     */
    public void bloomFilterExample() {
        RBloomFilter<String> bloomFilter = createBloomFilter("myBloomFilter", 10000, 0.01);
        // 添加元素
        bloomFilter.add("item1");
        // 判断元素是否存在
        boolean exists = bloomFilter.contains("item1");
    }
}

分布式锁测试

    @Autowired
    private RedissonUtils redissonUtils;

    @SneakyThrows
    @Test
    void ts() {
        // 获取分布式锁
            RLock lock = redissonUtils.getLock("myLock");

        // 尝试在 30 秒内获取锁,如果超时则返回 false
        if (lock.tryLock(300, 300, java.util.concurrent.TimeUnit.SECONDS)) {
            try {
                // 执行任务
                System.out.println("Executing critical section with distributed lock...");
            } finally {
                lock.unlock();  // 释放锁
            }
        } else {
            System.out.println("Failed to acquire lock.");
        }

    }

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐