Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用redis在多台服务器上共享会话_Redis_Asp.net Core_.net Core_Stackexchange.redis - Fatal编程技术网

使用redis在多台服务器上共享会话

使用redis在多台服务器上共享会话,redis,asp.net-core,.net-core,stackexchange.redis,Redis,Asp.net Core,.net Core,Stackexchange.redis,我正在.NET Core中实现一个分布式redis缓存,以便在微服务环境中的多个.NET Core服务之间共享。微服务位于IIS上负载平衡器后面的多台服务器上。redis缓存将用于临时保存与单个用户相关的数据。redis服务器将在内部托管。我已经有一个用于外部身份验证(AuthCookie)的cookie,但我不使用标识或会话,因为预期用户将登录。我只是将AuthCookie发送到我的身份验证服务,它进行身份验证,然后我用结果填充我的ClaimsPrincipal 由于我的缓存将是特定于用户的,

我正在.NET Core中实现一个分布式redis缓存,以便在微服务环境中的多个.NET Core服务之间共享。微服务位于IIS上负载平衡器后面的多台服务器上。redis缓存将用于临时保存与单个用户相关的数据。redis服务器将在内部托管。我已经有一个用于外部身份验证(AuthCookie)的cookie,但我不使用标识或会话,因为预期用户将登录。我只是将AuthCookie发送到我的身份验证服务,它进行身份验证,然后我用结果填充我的ClaimsPrincipal

由于我的缓存将是特定于用户的,所以我认为利用.Net会话和redis分布式缓存备份将是一个好主意。我想使用AuthCookie作为密钥,但它失败了,因为它不知道如何解密,这太糟糕了。因此,我必须有第二个.net会话特定cookie。问题是,会话在我的负载平衡器上的服务器之间无法工作,即使保留了我的密钥。以下是我的设置的简单版本:

public void ConfigureServices(IServiceCollection services)
{
    var host = "127.0.0.1";
    var port = "6379";
    var conn = $"{host}:{port}";
    var redis = ConnectionMultiplexer.Connect(conn);

    services.AddDataProtection().PersistKeysToRedis(redis, "DataProtection-Keys");

    services.AddDistributedRedisCache(options =>
    {
        options.Configuration = conn;
        options.InstanceName = "master";
    });
    services.AddSession(options => options.CookieName = "NetSession");
    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc();
}

public class RedisController : Controller
{
    public string Get(string key)
    {
        return HttpContext.Session.GetString(key);
    }

    public string Post([FromBody] CacheData data)
    {
        HttpContext.Session.SetString(data.Key, data.Value);
        return $"Added {data.Key} with {data.Value}";
    }
}
这在一台服务器上可以正常工作,但在我的负载平衡器上设置3个实例是行不通的。我调用负载平衡器,它在服务器a上设置一个密钥,redis将显示为masterSOMEGUID,并返回一个长的“NetSession”cookie。我在负载平衡器上调用get,服务器B将其接收,“NetSession”被发送,但当试图查找密钥时,它会生成一个不同的GUID,并且找不到它。如果我再次点击服务器A,它会发现它没有问题。我不知道我做错了什么

我发现的另一个解决方案是不使用会话,只使用IDistributedCache和已在请求中的AuthCookie

public class RedisController : Controller
{
    private readonly IDistributedCache _cache;
    public RedisController(IDistributedCache cache)
    {
        _cache = cache
    }
    public string Get(string key)
    {
        return _cache.GetString($"{HttpContext.Request.Cookies["NetSession"]}{key}");
    }

    public string Post([FromBody] CacheData data)
    {
       _cache.SetString($"{HttpContext.Request.Cookies["NetSession"]}{data.Key}", data.Value);
        return $"Added {data.Key} with {data.Value}";
    }
}

这显然会在redis商店中创建更多的条目。这样做不好吗?需要注意的是,我不会存储用户详细信息,只存储用户响应和其他可重用信息。

您解决了吗?您解决了吗?