创建后是否可以将Express Session更改为其他商店

时间:2018-07-06 00:44:15

标签: javascript node.js express express-session

我将memcached用作ExpressJS会话的后备存储-通过应用程序配置设置进行选择。如果无法联系memcached主机,我想从memcached退回到内存。 (这不一定是生产策略,因为memcached非常可靠-当我忘记在dev中启动Docker实例时,它的使用更多,但仍可能是生产故障保护。)

我首先以为我可以“ app.use”一个新的会话实例,并尝试删除第一个实例,但是我读到(如果可能的话)很难“不使用” Express中间件,即交换中间件在链中就位,或者通常在设置好链后进行修补。

存在连接超时时间之后的问题,已在会话中间件之后设置了应用中间件并安装了许多其他服务。

我的第二个想法是我可以重新配置Express Session实例本身,并在创建存储后对其进行更改吗?在the documentation中看不到任何方式。

我的第三个想法是将express-session包装在一个新的“可交换存储”类中,但是我对包装整个接口的范围保持警惕。

例如在我的应用设置中:

app.use(services.session.middleware());

// then a lot of other middleware...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(rootPath, 'public')));
...etc

在会话服务中,该服务选择并配置会话实例:

function middleware() {
    // default / Memory Store options
    const opts = {
        resave: false,
        saveUninitialized: false,
        ...etc
        }
    };

    // Install any configured backing store
    if(config.session.storage === "memcached"){
        const MemcachedStore = require('connect-memcached')(session);
        opts.proxy = 'true';
        opts.store = new MemcachedStore({
            hosts: ...,
            secret: ... 

        });
        const errorHandler = (type, details)=> {
            /* HERE I WOULD LIKE TO RE-MAKE THE SESSION USING MEMORY
             * AND DISCARD THE MEMCACHED ONE
             * (THIS HAPPENS AFTER APP BOOT HAS FINISHED)
            */
            console.error( String.format("Memcached {3} with host:{0} details:{1}.", details.server, details.messages.join( '' ), type)); 
        }
        opts.store.client.on('failure', details => errorHandler('failure', details));
        opts.store.client.on('issue', details => errorHandler('issue', details));
    }

    return session(opts);
}

1 个答案:

答案 0 :(得分:1)

我认为您可以尝试几种方法。第一种是根据您在启动时提供的配置来配置存储系统(可能通过config或nconf之类的模块)。第二种是在启动应用程序时进行快速检查,以确保它可以访问内存缓存服务,如果无法访问,则回退到内存并出现错误。

由于您使用的是docker,并且启动memcache应该很容易,因此我对执行上述任一操作都会感到厌倦。这是因为您将引入可能会在出现某些连接问题时在生产中触发的代码,然后您可能会发现自己不小心在内存中提供了会话,而不是像内存缓存之类的东西可能没有意识到。

我将在此处介绍这两种策略,并提供第三个可能更好的选择。

1。根据配置选择缓存系统

这应该很简单,只需将您的配置提取到某种配置管理器/环境变量(检出配置或nconf)中即可。启动应用程序并连接会话中间件时,您可以提取所有可能的配置,查看存在的配置并基于此进行配置。这类似于您的if (config.session.storage === 'memcache")目前的样子。只需使用未配置任何配置的后备选项,那么快速会话中间件将退回到内存中。这样,您可以完全省去配置,而总是使用内存进行开发。

2。连接到所需服务之前先运行测试

结合以上内容,如果提供了内存缓存详细信息,则可以通过在启动时尝试将某些内容存储在内存缓存中来运行快速测试。也许new Date();会在应用程序启动时发出信号?如果这会引发错误,则只需不要将MemcachedStore附加到express-session选项上,就可以安全地销毁MemcachedStore。

3。如果您无法连接到Memcached,则会引发错误

这是#2的进一步组合。如果您确定提供了内存缓存配置,那么我将亲自检查您是否可以联系服务部门,如果不能,则抛出错误并停止应用程序。这意味着在开发中您将立即知道该问题,在生产中您也将立即知道该问题,并且可以基于应用程序无法启动的事实为自己触发自动警报。

这可能是最好,最强大的解决方案,通常在谈论连接服务时,进行静默回退并不是一个好主意,因为事情可能会出错并且您一无所知。我了解这是出于开发目的,您需要务实,但是如果这样做可以避免您不小心从服务器内存中服务所有会话,那么这将是非常有益的。