- 如何监听redis键过期事件?
我在云函数中使用到了redis,并设置了一些key的24小时过期事件。该如何监听到key过期并触发云函数呢? 我考虑过一个方案: 设置一个定时触发器,每900秒执行一次,云函数内保持redis的连接,用redis的psubscribe/pmessage去监听 不知道这个方案是否可行。 我写了一个demo: exports.main = async (event, context) => { try { process.env.TZ = 'Asia/Shanghai';//时区 context.callbackWaitsForEmptyEventLoop = false; const { redis: redisUtil } = cache.createRedis() redisUtil.psubscribe('__keyevent@0__:expired', (err, count) => { if (err) { console.error("err", err); return; } console.log(`Subscribed to ${count} channels`); redisUtil.on('pmessage', async (pattern, channel, key) => { console.log(`pattern ${pattern} expired`); console.log(`channel ${channel} expired`); console.log(`Key ${key} expired`); // 在这里触发云函数并传递过期的键 const value = await redisUtil.hgetall(key); console.log(`Value ${value} expired`); }); }); setTimeout(() => { console.log("关闭redis"); redisUtil.quit(); }, 900 * 1000); } catch (error) { logger.error({ errorName: error.name, message: error.message, msg: '监听失败', }); } } 但好像监听不到。 redis里的参数也有配置的 [图片] 请教一下有没有懂这方面的
2023-05-20 - chrome无法唤起微信开发者工具
[图片] 电脑:macbook air 系统:Macos Mojave 版本:10.14.6 (18G9323) MacBook Air (13-inch, Early 2015) 1.6 GHz Intel Core i5
2023-04-10 - 云函数连接redis,能调用成功,。但日志一直超时,即使关闭了redis连接。请问是没有正确关闭吗?
// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境 const Redis = require('ioredis') const redis = new Redis({ host: "*******", port: '6379', // family: 4, password: '******', // db: 0 }) // 云函数入口函数 exports.main = async (event, context) => { const logger = cloud.logger() try { const wxContext = cloud.getWXContext() await redis.set('test-redis', "测试redis"); const data = await redis.get('test-redis') redis.disconnect(true); // await redis.quit() return { data, // event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID, } } catch (error) { // 记录日志 logger.error({ type: error.name, message: error.message, }); return { code: 1, msg: '失败', data: error.message } } } 如上图所示。我分别用了两种方法去关闭连接: redis.disconnect(true);这个能返回数据。但日志还是调用失败超时; [图片] [图片] 2. await redis.quit(); 这种方法日志显示调用成功。但是返回结果又是报错的。 [图片] 快要奔溃了。
2023-03-14 - 云函数连接redis后不关闭的话日志会总是报超时的错误。需要处理吗?在每个云函数里把redis连接关
[图片] /opt/utils/cache.js const Redis = require('ioredis') const redis = new Redis({ host: "xxx", port: '6379', // family: 4, password: 'xxx', // db: 0 }) exports.redis = redis // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境 const TcbRouter = require('tcb-router') const db = cloud.database() const _ = db.command const $ = db.command.aggregate const cache = require('/opt/utils/cache.js') // 使用到了云函数的层管理 const dateUtil = require('/opt/utils/dateUtil.js') // 使用到了云函数的层管理 // 云函数入口函数 exports.main = async (event, context) => { const app = new TcbRouter({ event }) // const { } = event const { OPENID, UNIONID } = cloud.getWXContext() const page = event.page ? Number(event.page) : 0; const pageSize = event.pageSize ? Number(event.pageSize) : 10; const skip = page * pageSize app.use(async (ctx, next) => { ctx.data = {} await next(); }); // 1.hot 热门问题(按回答人数) app.router('hot', async (ctx, next) => { try { const date = dateUtil.formatTime(new Date());//当前日期 const cacheKey = `question:hot:${date}:${page}:${pageSize}` const cacheKeyExists = await cache.redis.exists(cacheKey) const cacheData = await cache.redis.lrange(cacheKey, 0, -1); if (cacheKeyExists) { if (cacheData.length == 1 && cacheData[0] == 'EMPTY') { // 缓存结果为空 ctx.body = { code: 0, date, cacheKey, msg: '缓存结果空', data: [] } } else { // 有缓存 let result = [] for (let index = 0; index < cacheData.length; index++) { const element = JSON.parse(cacheData[index]); result.push(element) } ctx.body = { code: 0, date, cacheKey, msg: '缓存结果', data: result } } } else { // 从数据库查询数据 const { data } = await db.collection('question').where({ status: 'open', type: 'public' }).orderBy('total_answers', 'desc').skip(skip).limit(pageSize).field({ create_time: 1, title: 1, total_answers: 1, total_viewers: 1, total_collectors: 1, }).get(); if (data && data.length) { // 循环遍历存储到redis for (let index = 0; index < data.length; index++) { // 时间戳转日期 data[index].create_time = dateUtil.toDate(data[index].create_time) const element = JSON.stringify(data[index]); await cache.redis.rpush(cacheKey, element); await cache.redis.expire(cacheKey, 60 * 60 * 24);//24小时过期 } } else { // 数据为空时,设置缓存值为特殊字符串'EMPTY' await cache.redis.rpush(cacheKey, 'EMPTY', () => { cache.redis.expire(cacheKey, 60 * 60 * 24);//24小时过期 }) } ctx.body = { code: 0, date, cacheKey, msg: '数据库结果', data } } } catch (error) { ctx.body = { code: 1, msg: '获取热门问题失败', data: error } } finally { cache.redis.disconnect() } }) // 2.latest 最新问题 app.router('latest', async (ctx, next) => { try { const date = dateUtil.formatTime(new Date());//当前日期 const cacheKey = `question:latest:${date}:${page}:${pageSize}` const cacheKeyExists = await cache.redis.exists(cacheKey) const cacheData = await cache.redis.lrange(cacheKey, 0, -1); if (cacheKeyExists) { if (cacheData.length == 1 && cacheData[0] == 'EMPTY') { // 缓存结果为空 ctx.body = { code: 0, date, cacheKey, msg: '缓存结果空', data: [] } } else { // 有缓存 let result = [] for (let index = 0; index < cacheData.length; index++) { const element = JSON.parse(cacheData[index]); result.push(element) } ctx.body = { code: 0, date, cacheKey, msg: '缓存结果', data: result } } } else { // 从数据库查询数据 const { data } = await db.collection('question').where({ status: 'open', type: 'public' }).orderBy('create_time', 'desc').skip(skip).limit(pageSize).field({ create_time: 1, title: 1, total_answers: 1, total_viewers: 1, total_collectors: 1, }).get(); if (data && data.length) { // 循环遍历存储到redis for (let index = 0; index < data.length; index++) { // 时间戳转日期 data[index].create_time = dateUtil.toDate(data[index].create_time) const element = JSON.stringify(data[index]); await cache.redis.rpush(cacheKey, element); await cache.redis.expire(cacheKey, 60 * 60 * 24);//24小时过期 } } else { // 数据为空时,设置缓存值为特殊字符串'EMPTY' await cache.redis.rpush(cacheKey, 'EMPTY', () => { cache.redis.expire(cacheKey, 60 * 60 * 24);//24小时过期 }) } ctx.body = { code: 0, date, cacheKey, msg: '数据库结果', data } } } catch (error) { ctx.body = { code: 1, msg: '获取最新问题失败', data: error } } finally { cache.redis.disconnect() } }) return app.serve(); } 如上图代码中,每个云函数中 调用cache.redis.disconnect()就能调用成功。 这样做的话会有性能上的影响吗?这样每次调用云函数都要重新连接redis吧? 还是有什么更好的办法忽略掉日志的错误吗?
2023-03-08 - 云开发环境id如何通过配置文件去读取?
wx.cloud.init({ env: 'test-x1dzi' }) 开发环境和生产环境下的云环境ID是不一样的。怎样能通过配置文件的方式去读取,而不是直接硬编码。
2023-02-27