定时任务:SchedulingConfigurer接口,分布式环境Redis加锁


参照链接:https://blog.csdn.net/u014248473/article/details/91957731

扩展

一、Jedis加锁

1.1 pom.xml依赖:

<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.1</version>
        </dependency>

1.2 jedis配置类


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * <p>
 * redis配置类
 * </p>
 *
 * @author DELL
 * @since 2023/5/25 18:55
 */
@Configuration
public class JedisConfig {

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

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

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

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

    @Bean
    public JedisPool jedisPoolFactory() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 连接耗尽时是否阻塞,false报异常,默认true
        jedisPoolConfig.setBlockWhenExhausted(false);
        // 是否桥那个pool的jmx管理功能,默认true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, 10000, password);
        return jedisPool;
    }

    
}

 1.3 业务应用

package ccc.xxxx.fff;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.time.LocalDateTime;

/**
 * <p>
 * 定时任务:BaseSchedule
 * </p>
 *
 * @author DELL
 * @since 2023/5/25 10:19
 */
@Configuration
@EnableScheduling
@Slf4j
public class CompleteScheduleConfig implements SchedulingConfigurer {

    @Autowired
    private XxxService xxxService;

    @Mapper
    public interface CronMapper {
        @Select("select cron from cron limit 1")
        String getCron();
    }

    @Autowired
    @SuppressWarnings("all")
    CronMapper cronMapper;


    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> log.info("\n远期的到单在付款日前一天调用开始: " + LocalDateTime.now().toLocalTime()),
                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1 从数据库获取执行周期
                    String cron = cronMapper.getCron();
                    //2.2 合法性校验.
                    if (ObjectUtils.isNotEmpty(cron)) {
                        // Omitted Code ..
                        xxxService.arrivalOrderSenEmail(cron.getEmail());
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron.getCron()).nextExecutionTime(triggerContext);
                }
        );
    }


}

二、redisson 加锁

2.1 pom.xml依赖:

<dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.13.6</version>
        </dependency>

2.2 Redisson配置类 


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * <p>
 * redis配置类
 * </p>
 *
 * @author DELL
 * @since 2023/5/25 18:55
 */
@Configuration
public class JedisConfig {

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

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

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

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


    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://" +host + ":" + port).setPassword(password);
        return Redisson.create(config);
    }
}

 2.3 业务应用 


import com.haier.cz.web.common.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPool;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 到单定时任务:BaseSchedule
 * </p>
 *
 * @author DELL
 * @since 2023/5/25 10:19
 */
@Configuration
@EnableScheduling
@Slf4j
@Component
public class CompleteScheduleConfig implements SchedulingConfigurer {


    @Autowired
    private RedissonClient redissonClient;


    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        String uuid = StringUtils.getUuid();
        RLock lock = redissonClient.getLock("credit_no:" + uuid);
        try {

            boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
            if (isLock) {
                taskRegistrar.addTriggerTask(
                        // 略。。。。。。。。。。。。。。
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("向redis中设置key异常!");
        } finally {
            lock.unlock();
        }
    }


}

三、总结

 jedis和redisson 是两种不同的加锁方式:

3.1 jedis加锁:带着key,唯一标识,和过期时间进行加锁,底层通过setNx实现,谁拿到锁谁执行,弊端:业务流程过于长时,没执行完锁就被释放了。

3.2 redisson 应用相对来说比较简单,受Redis版本控制,老版本没有,最大的特点就是锁续命,在业务流程未执行完时,自动续时间,底层是通过看门狗机制完成->后台线程会不断的尝试拿锁

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值