真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

redis如何實(shí)現(xiàn)定時(shí)任務(wù)-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)redis如何實(shí)現(xiàn)定時(shí)任務(wù),小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)建站是專業(yè)的韶山網(wǎng)站建設(shè)公司,韶山接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行韶山網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

技術(shù)棧

redis / nodeJs / koa

技術(shù)重難點(diǎn)

  • 開啟redis的鍵空間通知功能(2.8.0及以上的版本才有此功能)

  • 盡量使用單獨(dú)的redis db來實(shí)現(xiàn)

  • 使用基于redis的分布式鎖來實(shí)現(xiàn)相關(guān)事件不會(huì)被重復(fù)消費(fèi)

  • 需要二次使用的信息需要體現(xiàn)在redis緩存的key中

  • redis cache key使用業(yè)務(wù)前綴,避免重名覆蓋

  • 防止業(yè)務(wù)服務(wù)重啟導(dǎo)致nodejs層面的監(jiān)聽失效

"talk is cheap, show me the code ?"

核心代碼

核心代碼
const { saveClient, subClient } = require('./db/redis') // 存儲(chǔ)實(shí)例和訂閱實(shí)例需要為兩個(gè)不同的實(shí)例
const processor = require('./service/task')
const config = require('./config/index')
const innerDistributedLockKey = '&&__&&' // 內(nèi)部使用的分布式鎖的key的特征值
const innerDistributedLockKeyReg = new RegExp(`^${innerDistributedLockKey}`)

saveClient.on('ready', async () => {
 saveClient.config('SET', 'notify-keyspace-events', 'Ex') // 存儲(chǔ)實(shí)例設(shè)置為推送鍵過期事件
 console.log('redis init success')
})

subClient.on('ready', () => { // 服務(wù)重啟后依舊可以初始化所有processor
 subClient.subscribe(`__keyevent@${config.redis.sub.db}__:expired`) // 訂閱實(shí)例負(fù)責(zé)訂閱消息
 subClient.on('message', async (cahnnel, expiredKey) => {
  // 分布式鎖的key不做監(jiān)聽處理
  if (expiredKey.match(innerDistributedLockKeyReg)) return
  // 簡(jiǎn)易分布式鎖,拿到鎖的實(shí)例消費(fèi)event
  const cackeKey = `${innerDistributedLockKey}-${expiredKey}`
  const lock = await saveClient.set(cackeKey, 2, 'ex', 5, 'nx') // 這里的用法可以實(shí)現(xiàn)簡(jiǎn)易的分布式鎖
  if (lock === 'OK') {
   await saveClient.del(cackeKey)
   for (let key in processor) {
    processor[key](expiredKey) // processor對(duì)應(yīng)的是接收到相關(guān)鍵過期通知后執(zhí)行的業(yè)務(wù)邏輯,比如推送短信,然后在相關(guān)processor中再次set一個(gè)定時(shí)過期的key
   }
  }
 })
 console.log('subClient init success')
})
servide/task (processor)
exports.sendMessage = async function sendMessage(expiredKey, subClient) {
 // 只處理相關(guān)業(yè)務(wù)的過期事件
 if (expiredKey.match(/^send_message/)) {
  const [prefix, userId, type] = expiredKey.split('-')
  let user = getUser(userId)
  if (user.phone) {
   push(message) // 偽代碼
   resetRedisKey(expiredKey, ttl) // 重新把key設(shè)置為一段時(shí)間后過期,過期后會(huì)再次觸發(fā)本邏輯
  }
 }
}

總結(jié)

  • 此功能利用了redis的鍵空間通知功能實(shí)現(xiàn)了簡(jiǎn)單了基于用戶或者基于不同業(yè)務(wù)場(chǎng)景的定時(shí)任務(wù)功能。由于鍵空間事件通知功能是一個(gè)較消耗CPU的操作,所以建議使用單獨(dú)的DB來處理。

  • 這里展示出來的是基本用法,未考慮定時(shí)任務(wù)的持久化功能,如果使用過程中redis故障重啟,則會(huì)導(dǎo)致所有定時(shí)任務(wù)丟失。如果在redis發(fā)布鍵失效通知時(shí),訂閱服務(wù)出故障未在線,或者網(wǎng)絡(luò)問題沒有被消費(fèi)方收到,也會(huì)導(dǎo)致此次事件丟失。

  • redis的expired事件并不是在key過期的時(shí)候觸發(fā),而是在key被刪除的時(shí)候觸發(fā)。redis會(huì)定期清理過期的key,或者當(dāng)訪問key的時(shí)候檢查是否過期,只有這時(shí)過期的key才會(huì)觸發(fā)刪除操作,因此會(huì)有一些小的時(shí)間差距(個(gè)人的實(shí)際使用中并沒有影響用戶體驗(yàn))。

因此需要權(quán)衡使用redis的過期機(jī)制實(shí)現(xiàn)的定時(shí)任務(wù)的使用場(chǎng)景。

關(guān)于“redis如何實(shí)現(xiàn)定時(shí)任務(wù)”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


標(biāo)題名稱:redis如何實(shí)現(xiàn)定時(shí)任務(wù)-創(chuàng)新互聯(lián)
本文來源:http://weahome.cn/article/hhogs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部