asp.net mvc 用Redis實現分布式集群共享Session

jopen 9年前發布 | 22K 次閱讀 Redis NoSQL數據庫

1、這兩天研究Redis搞分布式session問題,網上找的資料都是用ServiceStack.Redis來實現的,但是在做性能測試的時候發現最新的 v4版本有限制每小時候最多請求6000次,因為官網開始商業化要收費了,好坑爹的說,還好我前期弄了個性能測試列子,不然上線以后出問題那就麻煩了。后面找了個NServiceKit.Redis(好像就是ServiceStack.Redis的v3版本)來替代v4的收費版。

2、解決方案是 Redis+cookie方式實現記錄用戶登錄狀態

cookie:存放用戶的ID,這個ID是經過加密的,并且后臺可以通過密鑰解密。

Redis:key/value 方式存儲,key存放比如:user_1。  value存放用戶實體對象。

3、先安裝一個Redis,windows的版本在本地進行測試,后期上線更換linux系統的Redis替換一下ip就可以了。

4、添加一個Session管理類

public class SessionHelper
{
  private const int secondsTimeOut = 60 * 20;  
  public RedisHelper Redis = new RedisHelper(false);
  public LoginUserInfo this[string key]
  {
    get
    {
      string webCookie = WebHelper.GetCookie(key);
      if (webCookie == "")
      {
        return null;
      }
      key = key + "_" + SecureHelper.AESDecrypt(webCookie);

      long l = Redis.TTL(key);
      if (l >= 0)
      {
        Redis.Expire(key, secondsTimeOut);
      }
      return Redis.Get<LoginUserInfo>(key);
    }
    set
    {
      SetSession(key, value);
    }
  }
  public void SetSession(string key, LoginUserInfo value)
  {
    if (string.IsNullOrWhiteSpace(key))
    {
      throw new Exception("Key is Null or Epmty");
    }
    WebHelper.SetCookie(key, SecureHelper.AESEncrypt(value.ID.ToString()));
    key = key + "_" + value.ID;
    Redis.Set<LoginUserInfo>(key, value, secondsTimeOut);
  }





  public bool Remove(string key)
  {
    var rs = Redis.Remove(key + "_" + SecureHelper.AESDecrypt(WebHelper.GetCookie(key)));
    WebHelper.DeleteCookie(key);
    return rs;
  }
}

5、Redis操作類

public class RedisHelper : IDisposable
{
   private RedisClient Redis = new RedisClient("127.0.0.1", 6379);

  PooledRedisClientManager prcm = new PooledRedisClientManager();

  public int secondsTimeOut = 20 * 60;






  public static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
  {
    return new PooledRedisClientManager(readWriteHosts, readOnlyHosts,
      new RedisClientManagerConfig
      {
        MaxWritePoolSize = readWriteHosts.Length * 5,
        MaxReadPoolSize = readOnlyHosts.Length * 5,
        AutoStart = true,
      }); 
  }




  public RedisHelper(bool OpenPooledRedis = false)
  {
    if (OpenPooledRedis)
    {
      prcm = CreateManager(new string[] { "127.0.0.1:6379" }, new string[] { "127.0.0.1:6379" });
      Redis = prcm.GetClient() as RedisClient;
    }
  }





  public long TTL(string key)
  {
    return Redis.Ttl(key);
  }





  public void Expire(string key,int timeout = 0)
  {
    if (timeout >= 0)
    {
      if (timeout > 0)
      {
        secondsTimeOut = timeout;
      }
      Redis.Expire(key, secondsTimeOut);
    }
  }
  #region Key/Value存儲








  public bool Set<T>(string key, T t, int timeout = 0)
  {
    Redis.Set<T>(key, t);
    if (timeout >= 0)
    {
      if (timeout > 0)
      {
        secondsTimeOut = timeout;
      }
      Redis.Expire(key, secondsTimeOut);
    }
    return true;
  }






  public T Get<T>(string key)
  {
    return Redis.Get<T>(key);
  }





  public bool Remove(string key)
  {
    return Redis.Remove(key);
  }
  #endregion

  public void Dispose()
  {
    if (Redis != null)
    {
      Redis.Dispose();
      Redis = null;
    }
    GC.Collect();
  }
}
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!