当数据库不可用时阻止路由(优雅 "shutdown")

block routes when database unavailable (graceful "shutdown")

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

// 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数据库中的数据,没有这些数据,我不希望人们做事。

这可能不是我正在做的最好的方法 + 发送 "global" 错误 503 是个好主意,还是检查每条不同的路线更好?

您不应该在应用程序级别执行此操作。理想情况下,它应该由您的基础设施处理。

在应用级别,实施健康检查路线,并在那里执行您的逻辑。例如:如果 mysql 或 redis 宕机,return 500 错误。 infra 将看到该错误并停止将流量路由到该实例/服务器/容器。