麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > Redis > 正文

基于redis實現定時任務的方法詳解

2020-10-28 21:29:16
字體:
來源:轉載
供稿:網友

前言

業務中碰到的需求(抽象描述一下):針對不同的用戶能夠實現不同時間的間隔循環任務。比如在用戶注冊成功24小時后給用戶推送相關短信等類似需求。

使用crontab?太重,且基本不現實,不可能給每一個用戶在服務器上生成一個定時任務。
定時輪詢?IO頻繁且效率太低

想到經常的使用的redis可以設置緩存時間,應該會有過期的事件通知吧,查了一下文檔,果然有相關配置,叫做“鍵空間事件通知”。具體說明可參考官方文檔。

技術棧

redis / nodeJs / koa

技術重難點

  • 開啟redis的鍵空間通知功能(2.8.0及以上的版本才有此功能)
  • 盡量使用單獨的redis db來實現
  • 使用基于redis的分布式鎖來實現相關事件不會被重復消費
  • 需要二次使用的信息需要體現在redis緩存的key中
  • redis cache key使用業務前綴,避免重名覆蓋
  • 防止業務服務重啟導致nodejs層面的監聽失效

"talk is cheap, show me the code 🤖"

核心代碼

核心代碼const { saveClient, subClient } = require('./db/redis') // 存儲實例和訂閱實例需要為兩個不同的實例const processor = require('./service/task')const config = require('./config/index')const innerDistributedLockKey = '&&__&&' // 內部使用的分布式鎖的key的特征值const innerDistributedLockKeyReg = new RegExp(`^${innerDistributedLockKey}`)saveClient.on('ready', async () => { saveClient.config('SET', 'notify-keyspace-events', 'Ex') // 存儲實例設置為推送鍵過期事件 console.log('redis init success')})subClient.on('ready', () => { // 服務重啟后依舊可以初始化所有processor subClient.subscribe(`__keyevent@${config.redis.sub.db}__:expired`) // 訂閱實例負責訂閱消息 subClient.on('message', async (cahnnel, expiredKey) => {  // 分布式鎖的key不做監聽處理  if (expiredKey.match(innerDistributedLockKeyReg)) return  // 簡易分布式鎖,拿到鎖的實例消費event  const cackeKey = `${innerDistributedLockKey}-${expiredKey}`  const lock = await saveClient.set(cackeKey, 2, 'ex', 5, 'nx') // 這里的用法可以實現簡易的分布式鎖  if (lock === 'OK') {   await saveClient.del(cackeKey)   for (let key in processor) {    processor[key](expiredKey) // processor對應的是接收到相關鍵過期通知后執行的業務邏輯,比如推送短信,然后在相關processor中再次set一個定時過期的key   }  } }) console.log('subClient init success')})
servide/task (processor)exports.sendMessage = async function sendMessage(expiredKey, subClient) { // 只處理相關業務的過期事件 if (expiredKey.match(/^send_message/)) {  const [prefix, userId, type] = expiredKey.split('-')  let user = getUser(userId)  if (user.phone) {   push(message) // 偽代碼   resetRedisKey(expiredKey, ttl) // 重新把key設置為一段時間后過期,過期后會再次觸發本邏輯  } }}

總結

  • 此功能利用了redis的鍵空間通知功能實現了簡單了基于用戶或者基于不同業務場景的定時任務功能。由于鍵空間事件通知功能是一個較消耗CPU的操作,所以建議使用單獨的DB來處理。
  • 這里展示出來的是基本用法,未考慮定時任務的持久化功能,如果使用過程中redis故障重啟,則會導致所有定時任務丟失。如果在redis發布鍵失效通知時,訂閱服務出故障未在線,或者網絡問題沒有被消費方收到,也會導致此次事件丟失。
  • redis的expired事件并不是在key過期的時候觸發,而是在key被刪除的時候觸發。redis會定期清理過期的key,或者當訪問key的時候檢查是否過期,只有這時過期的key才會觸發刪除操作,因此會有一些小的時間差距(個人的實際使用中并沒有影響用戶體驗)。

因此需要權衡使用redis的過期機制實現的定時任務的使用場景。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产一区在线视频观看 | 特一级黄色毛片 | 黄网站在线免费看 | 国产精品久久99精品毛片三a | 一级毛片免费高清 | 成人福利视频在 | 色屁屁xxxxⅹ免费视频 | 国产精品一区在线看 | 成人在线网站 | 国产成人自拍av | 久久精品23 | 成人在线观看一区二区三区 | 国产亚洲欧美视频 | 久久性生活免费视频 | 色污视频在线观看 | 99在线精品视频免费观看20 | 亚洲成a人在线 | 中文字幕电影免费播放 | 美女wc| 精品一区二区久久久 | 羞羞视频免费视频欧美 | 欧美成人精品一区二区男人小说 | 久久777国产线看观看精品 | 欧美日韩免费一区 | 精国产品一区二区三区 | 奶子吧naiziba.cc免费午夜片在线观看 | 亚洲字幕av | 国产流白浆高潮在线观看 | 日韩 综合 | 另类亚洲孕妇分娩网址 | www噜噜偷拍在线视频 | 91成人久久 | 午夜视频在线观看91 | 免费播放欧美毛片 | 九九热在线精品视频 | 日韩中文字幕一区二区三区 | 日本不卡视频在线观看 | 国产做爰 | 7777网站 | 久久精品视频亚洲 | 久久国产乱子伦精品 |