Home  >  Article  >  Java  >  How spring boot integrates redisson

How spring boot integrates redisson

PHPz
PHPzforward
2023-05-14 19:46:191700browse

Integration and Precautions

redisson supports redis environment, stand-alone, cluster, sentinel, cloud, etc.

Here we will talk aboutCluster modeWhat needs to be noted is that when redisson is started, it will detect whether the master/slave node is normal. Generally speaking, there is no problem with 3 shards, 3 masters and 3 slaves. But if the test environment has 1 shard, 1 master, 1 slave or 3 masters, it cannot be started.

In addition to the environment, you also need to pay attention to compatibility with or without passwords.

Manually inject redisson configuration

Under normal circumstances, the production environment has a password. If there is a password, it is recommended to manually inject the redisson configuration without using spring boot to help you integrate it, because spring boot may not be able to recognize the password.

@Configuration
public class RedissonConfiguration {
    @Value("${spring.redis.cluster.nodes}")
    private String node;
    @Value("${spring.redis.password:}")
    private String password;
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        String[] nodes = node.split(",");
        ClusterServersConfig clusterServersConfig = config.useClusterServers();
        for (String nodeAddress : nodes) {
            clusterServersConfig.addNodeAddress(prefixAddress(nodeAddress));
        }
        if (StringUtils.isNotBlank(password)) {
            clusterServersConfig.setPassword(password);
        }
        return Redisson.create(config);
    }
    private String prefixAddress(String address) {
        if (!StringUtils.isBlank(address) && !address.startsWith("redis")) {
            return "redis://" + address;
        }
        return address;
    }
}

You can tune some configurations based on your actual situation.

Of course, in addition to the password, another point is whether has ssl. The current company is using Amazon Cloud, there will be ssl

spring boot is compatible with redis, which can be found in Tianji in yaml configuration: Ssl: true, but for redisson, just add the prefix:

rediss:// ip: port or domain name

Specific yaml configuration

spring:
  redis:
    cluster:
      nodes: rediss://clustercfg.xxx
    password: 'xxx'
    timeout: 30000
    Ssl: true
    lettuce:
      pool:
        max-idle: 100

Using the mutual exclusion strategy of locks, there is no problem with this

@Scheduled(cron = "${xxx:0 0 */2 * * ?}")
public void createProcess() {
    RLock lock = redisson.getLock(key);
    try {
        if (lock.tryLock()) {
           // 执行运行程序
        } else {
            log.info("createProcess 获取锁失败");
        }
    } catch (Exception e) {
        log.error("xxx", e);
    } finally {
        // 是否有锁 && 是否当前线程
        if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

at first glance, but this reconstruction has many scheduled tasks, so it will involve a lot try catch the same code.

Annotation method

One of the ways to solve duplicate code is encapsulation, which is annotation aspect. I think the annotation method is more flexible

So

/**
 * Redisson 同步锁
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RedissonSyncLock {
    String pref();
    /**
     * 锁后缀,一般前缀根据业务来定,后缀是具体的场景
     */
    String keyEL();
    /**
     * 等待时长 【需要区分是互斥还是阻塞,互斥默认0就可以】
     */
    int waitSec() default 0;
}

needs an aspect

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class RedissonSyncLockAspect {
    private final Redisson redisson;
    @Around(value = "@annotation(xxx.RedissonSyncLock)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        RedissonSyncLock redissonSyncLock = signature.getMethod().getAnnotation(RedissonSyncLock.class);
        Object[] args = joinPoint.getArgs();
        String key = SpelUtil.parseSpel(signature.getMethod(), args, redissonSyncLock.keyEL());
        RLock lock = null;
        try {
            if (StringUtils.isNotBlank(key) && !StringUtils.equals(key, "null") 
                lock = redisson.getLock(redissonSyncLock.pref().concat(key));
                if (lock.tryLock(redissonSyncLock.waitSec(), TimeUnit.SECONDS)) {
                    return joinPoint.proceed();
                }
            }
            log.info("RedissonSyncLockAspect 上锁失败 {}", key);
        } finally {
            if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

How to use:

@RedissonSyncLock(pref = KeyConstant.xxx, keyEL = "#bean.accountNo")
private void xxx(Bean bean){
     // 程序执行
}

It is indeed more convenient to use.

The above is the detailed content of How spring boot integrates redisson. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete