- 引入
<redisson.version>3.15.4</redisson.version>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
- 配置
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfiguration {
@Autowired
private RedisProperties redisProperties;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setDatabase(redisProperties.getDatabase());
config.useSingleServer().setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
if (StringUtils.isNotBlank(redisProperties.getPassword())) {
config.useSingleServer().setPassword(redisProperties.getPassword());
}
return Redisson.create(config);
}
}
- 放入延时队列
import org.redisson.api.RedissonClient;
@Autowired
private RedissonClient redissonClient;
public static final String CardKitMessageDelayQueue = "QUEUE:CARD_KIT";
RBlockingDeque<CardKitRedisBo> blockingDeque = redissonClient
.getBlockingDeque(CardKitMessageDelayQueue);
RDelayedQueue<CardKitRedisBo> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
long delayInSeconds = calculateDifference(model.getSendTime(), LocalDateTime.now());
CardKitRedisBo cardKitRedisBo = new CardKitRedisBo();
cardKitRedisBo.setId(model.getId()).setTemplateId(model.getTemplateId());
delayedQueue.offer(cardKitRedisBo, delayInSeconds, TimeUnit.SECONDS);
- 监听延时队列
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class CardKitMessageListener implements ApplicationRunner {
public static final String CardKitMessageDelayQueue = "QUEUE:CARD_KIT";
public static final String CardKitMessageDelayLock = "LOCK:CARD_KIT";
@Resource
private RedissonClient redissonClient;
@Autowired
private Tracer tracer;
@Autowired
private CardKitService cardKitService;
@Override
public void run(ApplicationArguments args) {
new Thread(() -> {
RBlockingDeque<CardKitRedisBo> blockingDeque = redissonClient.getBlockingDeque(CardKitMessageDelayQueue);
while (true) {
RLock rLock = redissonClient.getLock(CardKitMessageDelayLock);
try {
boolean isLocked = rLock.tryLock(5, TimeUnit.SECONDS);
if (isLocked) {
Span span = tracer.nextSpan().name("OccupationMessage").start();
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
CardKitRedisBo poll = blockingDeque.take();
log.info("获取延时消息:{}", JSONUtil.toJsonStr(poll));
cardKitService.sendCardKit(poll);
} finally {
try {
rLock.unlock();
} catch (Exception ex) {
log.warn("锁释放失败:" + ex.getMessage());
}
try {
span.end();
} catch (Exception ex) {
log.error("失败", ex)
}
}
}
} catch (Exception ex) {
log.error("延迟消息处理异常:" + ex.getMessage(), ex);
}
}
}).start();
}
}