隊列的特點:解耦,削峯,異步
隊列的使用場景主要用於異步處理耗時操作。
前幾天開發好了優惠券模塊,在優惠券發放那裏使用到了隊列來進行異步處理,因公司規模較小,服務器配置只有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);
}
}