【发布时间】:2020-08-03 22:07:57
【问题描述】:
在我的 Nodejs 应用程序中,我使用了一个在我的 Redis 数据库中设置键的库。所以,我需要监听每个创建/更新密钥的请求,并在每个密钥上添加一个ttl(无论它是否已经存在)。
我有我的主要 Redis 客户端(向 Redis 数据库添加密钥):
const redisClient = createClient({
url: redisUrl,
tls: {
ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
},
})
我添加了另一个应该监听set事件的客户端:
const subscriberRedis = redisClient.duplicate()
function done(err) {
logger.error('Notifications not active')
if (err) {
logger.error(err.stack || err.message || err)
}
}
const eventType = 'notify-keyspace-events'
subscriberRedis.config('get', eventType, (err, conf) => {
if (err) {
logger.debug('subscriberRedis:get =>', err.message)
return done(err)
}
logger.debug('conf =>', conf)
if (conf[1].indexOf('EKx') < 0) {
subscriberRedis.config('set', eventType, conf[1] + 'EKx', function (err) {
if (err) {
logger.debug('subscriberRedis:set =>', err.message)
return done(err)
}
})
}
})
const EVENT_SET = '__keyevent@0__:set'
subscriberRedis.on('message', function (channel, key) {
switch (channel) {
case EVENT_SET:
logger.info('Key "' + key + '" set!')
break
}
})
subscriberRedis.subscribe(EVENT_SET)
当我运行此代码时,我会进入由subscriberRedis.config('set',...) 记录的日志subscriberRedis:set => ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context
我不确定我在这里缺少什么。
编辑
我把代码改成了这个,现在它可以工作了。但是,当我开始生产时,您认为“竞争条件”问题仍然存在吗?
const redisClient = createClient({
url: redisUrl,
tls: {
ca: Buffer.from(redisCertBase64, 'base64').toString('utf-8'),
},
})
/**
* Subscriber listening to `set` events
**/
const subscriber = redisClient.duplicate()
const EVENT_SET = '__keyevent@0__:set'
subscriber.on('message', function (channel, key) {
switch (channel) {
case EVENT_SET:
redisClient.expire(key, 300)
logger.debug('Key "'.red + key + '" set!'.yellow)
break
}
})
subscriber.subscribe(EVENT_SET)
【问题讨论】:
-
你检查过 RedisGears 吗?它可以注册任何你想要的事件并对其采取行动,并且一切都在 Redis 中运行
-
我没有。我会检查一下!感谢您的提示!
标签: node.js redis listener node-redis ioredis