【问题标题】:Microsoft.Web.RedisSessionStateProvider not saving valueMicrosoft.Web.RedisSessionStateProvider 不保存价值
【发布时间】:2019-08-29 20:02:49
【问题描述】:

问题

在 Razor 视图中未检索到会话值,导致逻辑错误。

环境

Redis sentinel 与 web 服务器上的哨兵,但只有一个 redis master 和一个 redis slave。 redis连接字符串同时指向master和slave。

代码

在视图之前的控制器中:

var fooLocal = fooMapper.Map(fooDbCall.GetFromDb(fooValue));

if (fooLocal != null)
{
    Session["FooSession"] = fooLocal.fooProperty;
}
else
{
    Session["FooSession"] = false;
}

在视图中

@if (fooRazorVal == 123)
{
    // show some stuff
}
else if (!((bool?)Session["FooSession"] ?? false) && (fooRazorVal2 == 456))
{
    // show error message
}
else
{
    // show other stuff
}

结果

即使有问题的帐户已通过代码和数据库返回以验证它不应为假,更不用说为空,也会显示错误消息。其他会话值可以很好地存储和检索,否则您甚至不会在我的过程中做到这一点。

调查

正如我所提到的,所有其他代码位和数据库都已经过验证。我添加了一个日志类,并且有很多这样的条目:

[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 4686063 => Can not lock, Someone else has lock and lockId is 636901606595110722
[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 26422156 => Lock taken with lockId: 636901606595110722
[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 4686063 => Can not lock, Someone else has lock and lockId is 636901606595110722

但是,鉴于它们的数量庞大,我想知道这是否真的是一个错误或 RedisSessionStateProvider 是否按预期工作。我确实看到它使用SETNX 来获取锁。不幸的是,我对 redis 语义不够精通,无法知道这是否会导致问题。

我在 Redis 文档中提到了 see a note,说明这是一种旧方法,而是改用 RedLock。但是,据我了解 RedLock,单个主/单个从设置是不够的,尽管它确实支持重试,所以它可能无论如何都可以工作。我也很好奇我是否应该推出一个简单的自定义提供程序,让 StackExhange 的 ConnectionMultiplexer 在没有额外锁或自定义脚本的情况下工作,如果我确实需要锁才能使用 RedLock 的 C# 库之一。

【问题讨论】:

    标签: asp.net-mvc razor redis stackexchange.redis azure-redis-cache


    【解决方案1】:

    根据设计,Redis 密钥在更新期间被锁定,您无需锁定它们。事实上,Redis 使用单个线程来处理命令,因此每个操作都是原子的。其他客户端在处理给定命令期间被阻止,这就是为什么您不能执行执行时间长的查询并且您会收到此错误。

    为了防止必须实现分布式锁。在不同进程必须以互斥方式操作共享资源的许多环境中,分布式锁是一种非常有用的原语。

    这里是不同语言的不同实现。

    实现

    这里有一些已经可用的实现链接,可供参考。

    Redlock-rb(Ruby 实现)。还有一个 Redlock-rb 的分支,它添加了一个 gem 以便于分发,也许还有更多。

    Redlock-py(Python 实现)。

    Aioredlock(Asyncio Python 实现)。

    Redlock-php (PHP implementation).

    PHPRedisMutex (further PHP implementation)

    Redsync.go (Go implementation).

    Redisson (Java implementation).

    Redis::DistLock (Perl implementation).

    Redlock-cpp (C++ implementation).

    Redlock-cs(C#/.NET 实现)。

    RedLock.net(C#/.NET 实现)。包括异步和锁定扩展支持。

    ScarletLock (C# .NET implementation with configurable datastore)

    node-redlock (NodeJS implementation). Includes support for lock extension.

    看看这是否有帮助。

    【讨论】:

    • 我无法更改 Microsoft Redis 提供程序来更改其锁定方式。您能想到的还有什么可以帮助缓解这个问题的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 2016-11-12
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多