Maison  >  Article  >  Java  >  Comment Spring Boot intègre Redisson

Comment Spring Boot intègre Redisson

PHPz
PHPzavant
2023-05-14 19:46:191742parcourir

Intégration et précautions

redisson prend en charge l'environnement redis, autonome, cluster, sentinelle, cloud, etc.

Ici, nous parlerons du Mode clusterÀ quoi il faut prêter attention, le démarrage de Redisson détectera si le nœud maître/esclave est normal. De manière générale, il n'y a pas de problème avec 3 fragments, 3 maîtres et 3 esclaves, mais. si l'environnement de test est à 1 fragment, 1 maître, 1 esclave ou 3 maîtres ne peuvent pas être démarrés.

En plus de l'environnement, vous devez également faire attention à la compatibilité avec ou sans mots de passe.

Injecter manuellement la configuration redisson

Dans des circonstances normales, l'environnement de production dispose d'un mot de passe. S'il existe un mot de passe, il est recommandé d'injecter manuellement la configuration Redisson sans utiliser Spring Boot pour vous aider à l'intégrer, car Spring Boot risque de ne pas être en mesure de reconnaître le mot de passe.

@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;
    }
}

Vous pouvez ajuster certaines configurations en fonction de votre situation réelle.

Bien sûr, en plus du mot de passe, il y a un autre point qui est s'il existe SSL La société que j'utilise actuellement est Amazon Cloud, et il y aura SSL

Spring boot est compatible avec redis. définissez-le dans la configuration yaml : Ssl : true, mais pour redisson Ajoutez simplement le préfixe :

rediss:// + ip : port ou nom de domaine

Configuration yaml spécifique

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

Utilisez la stratégie exclusion mutuelle du verrou At. à première vue, cela ressemble à ceci

@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();
        }
    }
}

Il n'y a rien C'est un problème, mais cette reconstruction a de nombreuses tâches planifiées, elle impliquera donc une grande partie du même code try catch.

Méthode d'annotation

L'un des moyens de résoudre le code en double est encapsulation, qui est aspect d'annotation Je pense que la méthode d'annotation est plus flexible

, donc

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

a besoin d'un 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();
            }
        }
    }
}

Méthode d'utilisation :

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

C'est en effet utilisé C'est plus pratique.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer