基于Redisson实现延时队列 redis.cluster

RedissonConfig配置

package com.hh.ota.config;

import com.hh.ota.dto.OtaTimeOut;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class RedissonConfig {

    @Value("${spring.redis.cluster.nodes}")
    private String host;
    @Value("${spring.redis.password:}")
    private String password;

    @Value("${spring.redis.env}")
    public String env;


    @Bean
    public RedissonClient redissonClient() {
        //redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
        String node = "redis://" + host;
        RedissonClient redisson = null;
        Config config = new Config();
        config.useClusterServers().addNodeAddress(node);
        if (StringUtils.isNotBlank(password)) {
            config.useClusterServers().setPassword(password);
        }
        redisson = Redisson.create(config);
        //可通过打印redisson.getConfig().toJSON().toString()来检测是否配置成功
        return redisson;
    }

    @Bean
    @Qualifier("timeoutQueue")
    public RDelayedQueue<Object> timeoutQueue() {
        RDelayedQueue<Object> req = null;
        try {
            req = redissonClient().getDelayedQueue(redissonClient()
                    .getBlockingQueue(env + "timeout:upgrade"));
        } catch (Exception e) {
            log.warn("获取延迟队列失败,原因:{}", e.getMessage());
        }

        return req;
    }

    @Bean
    @Qualifier("blockingQueue")
    public RBlockingQueue<Object> blockingQueue() {
        RBlockingQueue<Object> req = null;
        try {
            req = redissonClient().getBlockingQueue(env + "timeout:upgrade");
        } catch (Exception e) {
            log.warn("获取延迟队列失败,原因:{}", e.getMessage());
        }

        return req;
    }

}
package com.hh.ota.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hh.boot.common.entity.Response;
import com.hh.boot.common.exception.NEException;
import com.hh.boot.common.util.ResponseUtil;
import com.hh.common.entity.admin.messageplatform.form.NotificationForm;
import com.hh.common.entity.app.newuser.UserExtendResp;
import com.hh.common.executor.AsyncExecutor;
import com.hh.common.executor.AsyncJob;
import com.hh.common.utils.AESCharacterUtils;
import com.hh.ota.client.IMessagePlatformServiceClient;
import com.hh.ota.client.IUserCoreDataServiceClient;
import com.hh.ota.client.IUserServiceClient;
import com.hh.ota.client.IVehicleCoreDataServiceClient;
import com.hh.ota.controller.idcm.OtaIdcmInformationController;
import com.hh.ota.dto.OtaSendTimeOut;
import com.hh.ota.dto.OtaTimeOut;
import com.hh.ota.dto.TimeOut;
import com.hh.ota.entity.UpgradeRecordEntity;
import com.hh.ota.form.kafkaFrom;
import com.hh.ota.kafka.KafkaProduct;
import com.hh.ota.service.UpgradeRecordService;
import com.hh.ota.utils.Constant;
import com.hh.ota.utils.Constants;
import com.hh.ota.utils.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import static com.hh.ota.utils.Constant.HA1;

/**
 * 过期队列
 */
@Component
@Slf4j
public class TimeoutHandler implements ApplicationListener<ContextClosedEvent> {

    private final Thread handlerThread = new Thread(new TimeoutTask());
    @Resource
    private RBlockingQueue<TimeOut> blockingQueue;
    @Resource
    private RDelayedQueue<TimeOut> timeoutQueue;
    

    private static volatile boolean lifeFlg = false;

    @PostConstruct
    public void init() {

        lifeFlg = true;
        handlerThread.start();
        log.info("超时队列处理器启动成功。");

    }

    
    @Async
    protected void handleTimeoutCmd(TimeOut timeOut) {
        //超时执行数据

        String vin = "";
        if(timeOut instanceof OtaTimeOut){
            

        }else if (timeOut instanceof OtaSendTimeOut){
       
        }
    }

   

    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        lifeFlg = false;
    }

    class TimeoutTask implements Runnable {

        @Override
        public void run() {

            while (lifeFlg) {

                try {
                    TimeOut timeoutCmd =  blockingQueue.take();
                    log.info("超时队列执行入参:{}", JSON.toJSONString(timeoutCmd));
                    handleTimeoutCmd(timeoutCmd);
                    log.info("超时队列执行结束");
                } catch (Exception e) {
                    log.warn("超时队列处理器发生错误:{}", e.getMessage());
                }
            }

        }
    }

    //添加
    public void offer(Supplier<TimeOut> supplier, Long timeOut) {
        Object cmd = supplier.get();
        log.info("添加超时队列元素入参:{}", JSON.toJSONString(cmd));
        timeoutQueue.offer(supplier.get(), timeOut, TimeUnit.SECONDS);
    }


    public void remove(Supplier<TimeOut> supplier) {
        Object cmd = supplier.get();
        log.info("超时队列元素删除入参:{}", JSON.toJSONString(cmd));
        boolean result = timeoutQueue.remove(cmd);
        log.info("超时队列元素删除结果:{}", result);
    }

}

添加超时队列

timeoutHandler.offer((()->{
                XX xx = new XX();
                
                return xx;
            }),Long.valueOf(outTime));

删除延时队列

timeoutHandler.remove(()->{
                XX xx = new XX();
            
                return xx;
            });

yml配置文件

 redis:
    env: 'pro:xx:'
    password: 
    database: 0
    port: 6379
    timeout: 60000
    cluster:
      nodes:
        xx
      max-redirects: 3
      refresh:
        period: 6000
        adaptive: true
    lettuce:
      pool:
        # 连接池最大连接数默认值为8
        max-active: 16
        # 连接池最大阻塞时间(使用负值表示没有限制)默认值为-1
        max-wait: 5000
        # 连接池中最大空闲连接数默认值为8
        max-idle: 16
        # 连接池中的最小空闲连接数,默认值为0
        min-idle: 4
        #eviction线程调度时间间隔
        time-between-eviction-run: 2000

你可能感兴趣的:(redis,spring,java)