队列的特点:解耦,削峰,异步
队列的使用场景主要用于异步处理耗时操作。
前几天开发好了优惠券模块,在优惠券发放那里使用到了队列来进行异步处理,因公司规模较小,服务器配置只有2G,安装MQ占用了宝贵的内存资源,于是就使用了Redis自带的消息队列来实现。
技术栈: Redis+Quartz定时任务
过程:当创建了优惠券分发任务的时候就把任务id扔到redis的队列里面,然后直接返回结果,Quartz定时任务收到然后处理定时任务。
直接上代码:
将任务添加到redis队列
PusCouponSendQueue pusCouponSendQueue = pusCouponSendQueueService.getById(id);
if(pusCouponSendQueue != null){
pusCouponSendQueue.setStatus(2);
pusCouponSendQueueService.updateById(pusCouponSendQueue);
//左推到redis队列
redisTemplate.opsForList().leftPush("coupon", id);
}
队列处理:
//每5秒钟读取一次队列
@Scheduled(cron = "0/5 * * * * *")
public void timer() {
String queueId = redisTemplate.opsForList().rightPop("coupon")+"";
log.info("优惠券发放消费者队列...(id="+queueId);
PusCouponSendQueue pusCouponSendQueue = null;
try{
if (!StringUtil.isNullOrEmpty(queueId) && !"null".equals(queueId)){
pusCouponSendQueue = pusCouponSendQueueService.getById(queueId);
if(pusCouponSendQueue != null){
if(0 == pusCouponSendQueue.getSendType()){ // 如果是全部发送
this.allSend(pusCouponSendQueue);
} else { // 部分发送
this.partSend(pusCouponSendQueue);
}
}
}
}catch(Exception e){ // 如果发生错误
e.printStackTrace();
pusCouponSendQueue.setStatus(-1);
pusCouponSendQueueService.updateById(pusCouponSendQueue);
}
//任务执行成功
if(pusCouponSendQueue != null){
pusCouponSendQueue.setStatus(3);
pusCouponSendQueueService.updateById(pusCouponSendQueue);
}
}