【问题标题】:NodeJS - Redis connection eventsNodeJS - Redis 连接事件
【发布时间】:2019-11-20 15:19:26
【问题描述】:

我的目标如下:

  • 仅在程序开始时一次连接到 Redis 实例。
  • module.exports的连接方法让一个文件可以requires这个对象并发起连接。然后将生成的客户端“传递”到其他模块。
  • 如果连接中断,则会引发相应的异常并进行相应处理。

我可以让前两个工作。但是,我不确定如何在我的项目源中处理 Redis elsewhere 的其他事件。

例子:

connect-once.js我正在连接async,以便调用函数可以await完成连接。

const redis = require('redis')
//
async function clientOperations(options) {
    let connObject = {}
    let redisClient = redis.createClient(options)
    return new Promise((resolve, reject) => {
        redisClient.on('error', (err) => {
            connObject = {
                cacheClient: {},
                connected: false
            }
            reject(connObject)
        })
        //
        redisClient.on('connect', () => {
            connObject = {
                cacheClient: redisClient,
                connected: true
            }
            resolve(connObject)
        })
    })
}
//
async function connect(options) {
    return new Promise(async (resolve, reject) => {
        try {
            let p = await clientOperations(options)
            resolve(p)
        } catch(e) {
            reject(e)
        }
    })
}
//
module.exports = { connect }

init.js

const cache = require('connect-once')
let cacheClient = await cache.connect()
//
const bizlogic = require('some-biz-logic')
await bizlogic.addcustomer({cacheClient : cacheClient, payload : express.req.payload})

在上面的 sn-p 中,当 Redis 连接在 bizlogic.addcustomer 中断开时会发生什么?也许,我也在想“程序化编程”。我很想知道如何连接一次,与项目的其余部分共享连接,并在项目中的某处使用该连接时处理任何连接错误。

【问题讨论】:

    标签: node.js events redis database-connection


    【解决方案1】:

    我建议使用 ioredis 而不是 redis npm i ioredis https://github.com/luin/ioredis#auto-reconnect

    默认情况下,ioredis 会在与 Redis 的连接丢失时尝试重新连接,除非连接关闭 通过 redis.disconnect() 或 redis.quit() 手动操作。

    使用 retryStrategy 选项可以非常灵活地控制断开连接后等待重新连接的时间:

    var redis = new Redis({
      // This is the default value of `retryStrategy`
      retryStrategy: function(times) {
        var delay = Math.min(times * 50, 2000);
        return delay;
      }
    });
    

    例如connect-once.js

    const Redis = require('ioredis');
    
    let connObject;
    
    //
    async function clientOperations(options) {
        if (connObject && connObject.connected) {
            return connObject;
        }
        let redisClient = Redis({
            host: options.host,
            port: options.port,
            password: options.password,
            lazyConnect: true,
        });
        await redisClient.connect();
        connObject = {
            cacheClinet: redisClient,
            connected: true
        }
        return connObject;
    }
    
    //
    async function connect(options) {
        return clientOperations(options);
    }
    //
    module.exports = { connect }
    

    【讨论】:

    • redis 包也会自动重新连接。事实上,它也会发出相同的事件。
    • ioredis :一个令人愉悦的、注重性能的、功能齐全的 Redis 客户端。支持集群、哨兵、流水线和 Lua 脚本 (redis.io/clients#nodejs)。 connObject 是共享的。默认情况下,每重试 20 次,所有挂起的命令都会被刷新并显示一个错误。这样可以确保在连接断开时命令不会永远等待。您可以通过设置 maxRetriesPerRequest 来更改此行为。
    • 我认为这可能已经过时或与打字稿的工作方式不同。还是有用的,谢谢。
    猜你喜欢
    • 2012-08-15
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多