参考:
1、(41条消息) redisson延迟队列解决延迟任务_Fly_Camel_Yu的博客-CSDN博客_redission 延迟任务
2、Redisson延迟队列RDelayedQueue的使用 - 灰信网(软件开发博客聚合) (freesion.com)
3、(41条消息) Redis通过Redisson实现延迟队列(含源码)_普通网友的博客-CSDN博客_redisson延迟队列实现原理
4、(41条消息) 多线程之BlockingQueue中 take、offer、put、add的一些比较_wei_ya_wen的博客-CSDN博客_blockingqueue offer
引入:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.4</version>
</dependency>
步骤:
1、创建bean对象
/**
* @author seeklife
* @date 2022年08月03日 14:54
*/
@Configuration
public class SynthesisResultDelayConfig {
@Autowired
private RedissonClient redissonClient;
@Bean("blockQueue")
public RBlockingDeque<SynthesisResultQryDto> getBlockQueue() { //取延迟任务
RBlockingDeque<SynthesisResultQryDto> blockingDeque =
redissonClient.getBlockingDeque("prompter:synthesis:task:result");
return blockingDeque;
}
@Bean("delayedQueue")
public RDelayedQueue<SynthesisResultQryDto> getDelayQueue() { //存延迟任务
RBlockingDeque<SynthesisResultQryDto> blockingDeque = getBlockQueue();
RDelayedQueue<SynthesisResultQryDto> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
return delayedQueue;
}
}
2、自定义对象,实现Serializable接口
/**
* @author seeklife
* @date 2022年08月03日 15:15
*/
@Data
@AllArgsConstructor
public class SynthesisResultQryDto implements Serializable {
private String msg;
private String type;
}
3、自己的业务逻辑
/**
* @author seeklife
* @date 2022年08月03日 15:18
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class RedissonDelayService<T> {
@Autowired
private GhOrderService ghOrderService;
@Autowired
private OrderService orderService;
@Async
public void accept(SynthesisResultQryDto qryDto) {
log.info("accept 查询订单 结果已出,msg:{}", qryDto.getMsg());
//执行到期业务逻辑
switch (DelayEnum.toType(qryDto.getType())){ //根据枚举匹配对应的业务逻辑执行
case ORDER_OUTTIME_UNPAY:
GhOrder order = ghOrderService.lambdaQuery()
.eq(GhOrder::getOrderNo, qryDto.getMsg()).one();
if(ObjectUtil.isNotNull(order)
&& order.getStatus().equals(OrderStatusEnum.ORDER_STATUS_0.getValue())){
orderService.cancelOrder(order.getOrderNo(), "", order.getUserId());
}
break;
}
}
}
/**
* @author seeklife
* @date 2022年08月03日 15:22
*/
@Slf4j
@Component
public class SynthesisResultDelayJob {
@Autowired
private RedissonDelayService<SynthesisResultQryDto> synthesisResultConsumer;
@Autowired
private RBlockingDeque<SynthesisResultQryDto> blockingDeque;
@PostConstruct
public void listen() {
new Thread(() -> {
while (true) {
try {
log.info("延时队列的数量:{}", blockingDeque.size());
log.info("listen 本次监听时间:{}", DateUtil.formatDate(new Date()));
SynthesisResultQryDto dto = blockingDeque.take(); //到期时自动取出
log.info("listen 从队列中获取需要查询结果的延时任务信息:{}", JSON.toJSONString(dto));
synthesisResultConsumer.accept(dto);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
4、需要延迟的地方,第二个参数为时间,第三个参数选择单位分钟,秒等。
@Autowired
private RDelayedQueue<SynthesisResultQryDto> delayedQueue;
delayedQueue.offer(new SynthesisResultQryDto(orderNo,DelayEnum.ORDER_OUTTIME_UNPAY.getValue()), 30, TimeUnit.MINUTES);
集成时出现了一个问题记录一下:
问题一:
启动服务时报错,一看是springsecurity的过滤器链存在两个实现类,我在想我引入redisson和springsecurity有啥关系?
Description:
Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a single bean, but 2 were found:
- requestMappingHandlerMapping: defined by method 'requestMappingHandlerMapping' in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]
- controllerEndpointHandlerMapping: defined by method 'controllerEndpointHandlerMapping' in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.class]
解决办法:
1、还原还没引入redisson时的状态,发现启动成功。猜想还是出在依赖问题上,看看有没冲突。
引入时排除一下。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.4</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</exclusion>
</exclusions>
</dependency>
问题二:
redisson简单使用--内存溢出异常:o.redisson.client.handler.CommandsQueue [153] : Exception - 掘金 (juejin.cn)