首页 > 解决方案 > Lucee/ColdFusion - 跨集群锁定会话范围并同时访问会话变量

问题描述

这个问题适用于 Lucee 5.x 应用程序。我不确定 ACF 和 Lucee 如何跨集群处理会话范围之间是否存在差异。

背景:我正在实现一个autoLogin()函数 in application.cfc- in onRequestStart()- 查找存储在 cookie 中的令牌,然后使用它来验证用户。使用令牌后,它会被新值替换,并且 cookie 会更新。当找不到令牌或令牌不起作用时,cookie 将被删除。会话锁用于防止多个并发请求尝试登录用户,这会产生意想不到的副作用。

这个工作的所有核心功能(在单个节点上),但我需要使它对集群友好。集群已经正确设置(this.sessionCluster = true;在 application.cfc 中,以及存储会话数据的共享 Memcached 实例),并且工作正常。

我的主要问题是:(参考下面的代码)

  1. 下面的代码使用独占会话锁来防止并发请求同时执行登录代码。您如何将下面的会话锁替换为在整个集群中锁定会话的锁?

  2. 下面的代码假定可以立即看到对会话变量的更改。当一个节点上的会话变量被更改,然后另一个节点上的并发请求试图访问同一个变量时,这是真的吗?如果没有,有没有办法刷新会话范围以确保您获得最新的?

下面是 autoLogin() 函数:(在单个节点上工作)

private void function autoLogin () {

    // multiple, concurrent requests could be hitting this on different nodes in the cluster

    // if we're already logged in, nothing to do
    if (session.isLoggedIn) {
        return;
    }

    // get the auth token if it exists
    var token = cookie.keyExists("auth") && isValid("uuid", cookie.auth) ? cookie.auth : "";
    if (token == "") {
        // if a token doesn't exists, nothing to do
        return;
    }

    // assertion: user is not logged in and an auth token exists
    // attempt to login using the token, but make sure that only one 
    // request does this at a time - wrap with an exclusive session lock

    // lock the session - how would you do this on a cluster?
    lock scope="session" type="exclusive" timeout="10" throwontimeout=false {
        // check if logged in again - another thread may have succeeded while this
        // thread was waiting for the lock to open
        if (!session.loggedIn) {
            // we can only call this once if user is not logged in!
            application.auth.loginWithToken(authToken=token);
        }
    }

} // autoLogin()

标签: sessioncoldfusioncluster-computingluceeapplication.cfc

解决方案


推荐阅读