好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > redis實現延時隊列的兩種方式(小結)

redis實現延時隊列的兩種方式(小結)

熱門標簽:鄭州人工智能電銷機器人系統 日本中國地圖標注 十堰營銷電銷機器人哪家便宜 山東外呼銷售系統招商 魔獸2青云地圖標注 北京400電話辦理收費標準 宿遷便宜外呼系統平臺 貴州電銷卡外呼系統 超呼電話機器人

背景

項目中的流程監控,有幾種節點,需要監控每一個節點是否超時。按傳統的做法,肯定是通過定時任務,去掃描然后判斷,但是定時任務有缺點:1,數據量大會慢;2,時間不好控制,太短,怕一次處理不完,太長狀態就會有延遲。所以就想到用延遲隊列的方式去實現。

一,redis的過期key監控

1,開啟過期key監聽

在redis的配置里把這個注釋去掉

notify-keyspace-events Ex

然后重啟redis

2,使用redis過期監聽實現延遲隊列

繼承KeyExpirationEventMessageListener類,實現父類的方法,就可以監聽key過期時間了。當有key過期,就會執行這里。這里就把需要的key過濾出來,然后發送給kafka隊列。

@Component
@Slf4j
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

  @Autowired
  private KafkaProducerService kafkaProducerService;

  public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
    super(listenerContainer);
  }

  /**
   * 針對 redis 數據失效事件,進行數據處理
   * @param message
   * @param pattern
   */
  @Override
  public void onMessage(Message message, byte[] pattern){
    if(message == null || StringUtils.isEmpty(message.toString())){
      return;
    }
    String content = message.toString();
    //key的格式為  flag:時效類型:運單號 示例如下
    try {
      if(content.startsWith(AbnConstant.EMS)){
        kafkaProducerService.sendMessageSync(TopicConstant.EMS_WAYBILL_ABN_QUEUE,content);
      }else if(content.startsWith(AbnConstant.YUNDA)){
        kafkaProducerService.sendMessageSync(TopicConstant.YUNDA_WAYBILL_ABN_QUEUE,content);
      }
    } catch (Exception e) {
      log.error("監控過期key,發送kafka異常,",e);
    }
  }
}

可以看的出來,這種方式其實是很簡單的,但是有幾個問題需要注意,一是,這個盡量單機運行,因為多臺機器都會執行,浪費cpu,增加數據庫負擔。二是,機器頻繁部署的時候,如果有時間間隔,會出現數據的漏處理。

二,redis的zset實現延遲隊列

1,生產者實現

可以看到生產者很簡單,其實就是利用zset的特性,給一個zset添加元素而已,而時間就是它的score。

public void produce(Integer taskId, long exeTime) {
  System.out.println("加入任務, taskId: " + taskId + ", exeTime: " + exeTime + ", 當前時間:" + LocalDateTime.now());
  RedisOps.getJedis().zadd(RedisOps.key, exeTime, String.valueOf(taskId));
}

2,消費者實現

消費者的代碼也不難,就是把已經過期的zset中的元素給刪除掉,然后處理數據。

public void consumer() {
  Executors.newSingleThreadExecutor().submit(new Runnable() {
    @Override
    public void run() {
      while (true) {
        SetString> taskIdSet = RedisOps.getJedis().zrangeByScore(RedisOps.key, 0, System.currentTimeMillis(), 0, 1);
        if (taskIdSet == null || taskIdSet.isEmpty()) {
          System.out.println("沒有任務");
 
        } else {
          taskIdSet.forEach(id -> {
            long result = RedisOps.getJedis().zrem(RedisOps.key, id);
            if (result == 1L) {
              System.out.println("從延時隊列中獲取到任務,taskId:" + id + " , 當前時間:" + LocalDateTime.now());
            }
          });
        }
        try {
          TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  });
}

可以看到這種方式其實是比上個方式要好的。因為,他的那兩個缺點都被克服掉了。多臺機器也沒事兒,也不用再擔心部署時間間隔長的問題。

總結

兩個方式都是不錯的,都能解決問題。碰到問題,多思考,多總結。

到此這篇關于redis實現延時隊列的兩種方式(小結)的文章就介紹到這了,更多相關redis 延時隊列內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • golang實現redis的延時消息隊列功能示例
  • 使用Redis實現延時任務的解決方案
  • 利用Redis實現延時處理的方法實例

標簽:果洛 朝陽 吉安 江蘇 臺州 大慶 北京 楊凌

巨人網絡通訊聲明:本文標題《redis實現延時隊列的兩種方式(小結)》,本文關鍵詞  redis,實現,延時,隊列,的,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《redis實現延時隊列的兩種方式(小結)》相關的同類信息!
  • 本頁收集關于redis實現延時隊列的兩種方式(小結)的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 啊灬啊灬别停啊灬用力啊动态图 | 98精品久久久亂倫| 正在播放国产精品放孕妇| 美女视频黄a全部| 0855午夜福利| 性xxxx欧美高清| 口述好大?好爽?快点| 美女撅着白嫩光屁股挨打| 一本久道视频一本久道| 91?口爆一区二区三区在线| 高清在线观看免费网站| jizz国产精品jizz中国| 欧美一级久久久猛烈A大片摄影师| gif动图哔哩哔哩| 欧美日韩亚洲国内综合网俺| 狠狠地进入| 竹溪县| sm调教惩罚-MaxXXX| 女学生20岁一级毛片| 玖玖精品视频在线| 99精品在线视频| 色吧亚洲欧美另类| 欧洲美女与动交zoz0z| 国产精品萌白酱在线观看| 人人澡人人干| 国产又粗又猛又色又黃动图视频 | 亚洲中文精品久久久久久图片区| 操女人的软件| 看美女的逼| 免费无码又爽又黄又刺激网站简爱 | 爽死你个放荡粗暴小淫货视频| 深夜福利APP导航排行榜| 亚洲色偷拍另类无码专区| 日本一区二区三区视频在线| 翁公和在厨房猛烈进出| 征服高贵美妇人后菊| 狍和女人一级毛片免费的| 成人字幕网视频在线观看| 忘忧草1688网站| 孕妇高潮XXXXX孕妇| 李恩美被躁120分钟在线播放|