Microsoft.Web.RedisSessionStateProvider未保存值

时间:2019-04-08 15:57:44

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

问题

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

环境

Redis哨兵与Web服务器上的哨兵,但只有一个redis主服务器和一个redis从属服务器。 Redis连接字符串指向主服务器和从服务器。

代码

在视图之前的控制器中:

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
}

结果

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

调查

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

[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在没有额外的锁或自定义脚本的情况下工作,并且如果我确实需要锁来使用Red Hat的C#库之一。

1 个答案:

答案 0 :(得分:0)

根据设计,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.

看看是否有帮助。