数据库不可用时阻止路由(优雅的“关闭”)

8oomwypt  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(387)

我正在nodejs中构建一个web服务器,它依赖于redis、postgresql和mongodb。我将所有凭据存储在googlecloudsecretmanager中,因此我必须使用异步函数来获取它们。到目前为止我的代码是:

// Redis.js

const { accessSecretVersion } = require('./google_cloud/secret-manager')

const Redis = require('redis')

// initialize connection (promise because accessSecretVersion is an async function)
const initialize = new Promise(async (resolve, reject) => {
    const redis = Redis.createClient({
        host: await accessSecretVersion('redis_host'),
        port: 6379
    })

    redis.on('error', err => reject(err))

    redis.on('connect', () => resolve(redis))    
}) 

module.exports = {
    initialize
}

// App.js

'use strict'

const express = require('express')

const app = express()

const bodyParser = require('body-parser')

app.use(bodyParser.json())

const Redis = require('./redis')

let redis

// try to initialize a connection
// then => it works!
// catch => it does not work!
Redis.initialize.then(redis => {
    redis = redis
    console.log('redis available')
}).catch(err => console.log(err))

// further on, other stuff rely on 'redis'
// if 'redis' is undefined, they crash, but I want a graceful "shutdown" of the functions

// here, the emitter relies on 'redis'
// the problem is, this code is ran BEFORE the redis connection 
// has established, so it returns an empty
// (when this code runs, 'redis' is still undefined)
const Io = require('./components/socket_io/emitter')(redis)

如您所见,在app.js上,我尝试创建一个redis连接。如果成功(在redis.js中解析),“let redis”设置为redis连接。如果不是(拒绝),我在控制台中记录错误。
问题是这个代码中的其他一些函数依赖于redis连接,比如socket.io-redis/socket.io-emitter。
我想要实现什么?
如果redis服务器关闭,我想发送一个全局状态码503(服务不可用),不管请求什么路由。服务器不应该崩溃,但应该是不可访问的,因为我的服务器中的许多功能依赖于redis数据库中的数据,没有这些数据,我不希望人们做任何事情。
这可能不是我正在做的最好的方法+发送“全局”错误503是个好主意,还是检查每个不同的路由更好?

eqfvzcg8

eqfvzcg81#

您不应该在应用程序级别执行此操作。理想情况下,它应该由您的infra处理。
在应用程序级别,实现一个健康检查路由,并在那里执行您的逻辑。例如:如果mysql或redis关闭,返回500错误。infra将看到该错误,并停止将流量路由到该示例/服务器/容器。

相关问题