分布式中使用Redis實現Session共享

2021-09-02 15:59:06 字數 4122 閱讀 4120

using system;

using system.collections.generic;

using system.linq;

using system.web;

using system.web.sessionstate;

using servicestack.redis;

using com.redis;

namespace residsessiondemo.redisdemo

/// /// sessionid識別符號

///

public static string sessionname = "redis_sessionid";

//// 摘要:

// 獲取會話狀態集合中的項數。

//// 返回結果:

// 集合中的項數。

public int count}//

// 摘要:

// 獲取乙個值,該值指示會話是否為唯讀。

//// 返回結果:

// 如果會話為唯讀,則為 true;否則為 false。

public bool isreadonly

//// 摘要:

// 獲取會話的唯一識別符號。

//// 返回結果:

// 唯一會話識別符號。

public string sessionid}//

// 摘要:

// 獲取並設定在會話狀態提供程式終止會話之前各請求之間所允許的時間(以分鐘為單位)。

//// 返回結果:

// 超時期限(以分鐘為單位)。

public int timeout

/// /// 獲取sessionid

///

/// sessionid識別符號

/// httpcookie值

private string getsessionid()

else}//

// 摘要:

// 按名稱獲取或設定會話值。

//// 引數:

// name:

// 會話值的鍵名。

//// 返回結果:

// 具有指定名稱的會話狀態值;如果該項不存在,則為 null。

public object this[string name]

set}

// 摘要:

// 判斷會話中是否存在指定key

//// 引數:

// name:

// 鍵值

//public bool i***istkey(string name)

//// 摘要:

// 向會話狀態集合新增乙個新項。

//// 引數:

// name:

// 要新增到會話狀態集合的項的名稱。

//// value:

// 要新增到會話狀態集合的項的值。

public void add(string name, object value)

//// 摘要:

// 從會話狀態集合中移除所有的鍵和值。

public void clear()

//// 摘要:

// 刪除會話狀態集合中的項。

//// 引數:

// name:

// 要從會話狀態集合中刪除的項的名稱。

public void remove(string name)

//// 摘要:

// 從會話狀態集合中移除所有的鍵和值。

public void removeall()}}

下面是實現類似在cs檔案中能直接使用session["userid"]的方式,我的mypage類繼承page實現了自己的邏輯主要做了兩件事  1:初始化redissession  2:實現統一登入認證,onpreinit方法裡面判斷使用者是否登入,如果沒有登入了則跳轉到登陸介面

using system;

using system.collections.generic;

using system.linq;

using system.web;

using system.web.ui;

namespace residsessiondemo.redisdemo

return redissession;}}

protected override void onpreinit(eventargs e)}}

}

我們來看看default.aspx.cs是如何使用redissession的,至此我們實現了和asp.netsession一模一樣的功能和使用方式。

redissession.remove("

usercode

");

相比stateserver,redissession具有以下優點

1.redis伺服器重啟不會丟失資料  2.可以使用redis的讀寫分離個集群功能更加高效讀寫資料

測試效果,使用nginx和iis部署兩個站點做負載均衡,iis1位址127.0.0.1:8002 iis2位址127.0.0.1:9000  nginx**服務位址127.0.0.1:8003,不懂如何配置的可以去閱讀我的nginx+iis實現負載均衡這篇文章。我們來看一下測試結果。

訪問127.0.0.1:8003 需要進行登入   使用者名為admin  密碼為123

登入成功以後,重點關注埠號資訊

重新整理頁面,重點關注埠號資訊

可以嘗試直接訪問iis1位址127.0.0.1:8002 iis2位址127.0.0.1:9000 這兩個站點,你會發現都不需要登入了。至此我們的redis實現session功能算是大功告成了。

先說下我知道的兩種方案:

1.使用流量整形中的令牌桶演算法,大小固定的令牌桶可自行以恆定的速率源源不斷地產生令牌。如果令牌不被消耗,或者被消耗的速度小於產生 的速度,令牌就會不斷地增多,直到把桶填滿。後面再產生的令牌就會從桶中溢位。最後桶中可以儲存的最大令牌數永遠不會超過桶的大小。

說淺顯點:比如上面的獲取access_token介面,一天2000次的頻率,即1次/分鐘。我們令牌桶容量為2000,可以使用redis 最簡單的key/value來儲存 ,key為使用者id,value為整形儲存還可使用次數,然後使用乙個定時器1分鐘呼叫client.incr(key) 實現次數自增;使用者每訪問一次該介面,相應的client.decr(key)來減少使用次數。

但是這裡存在乙個效能問題,這僅僅是針對乙個使用者來說,假設有10萬個使用者,怎麼使用定時器來實現這個自增操作呢,難道是迴圈10萬次分別呼叫client.incr(key)嗎?這一點沒有考慮清楚。

2.直接使用者訪問一次 先進行總次數判斷,符合條件再就進行一次自增

兩種方案優缺點比較

優點

缺點

令牌桶演算法

流量控制精確

實現複雜,並且由於控制精確反而在實際應用中有麻煩,很可能使用者在晚上到凌晨期間訪問介面次數不多,白天訪問次數多些。

簡單演算法

實現簡單可行,效率高

流量控制不精確

回到頂部

本篇從實際應用講解了redis,後面應該還會有幾篇繼續介紹redis實際應用,敬請期待!

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

使用Redis實現分布式鎖

網上大部分建議都是使用setnx,這個本身沒有什麼問題,因為低版本的redis中,只有這個命令可以互斥的set乙個key。但是隨著redis版本的公升高,提供了更多的命令來更好的滿足我們的需求。set keyvalue ex seconds px milliseconds nx xx 這可和你所知道...

使用redis 實現分布式鎖

在有些需要高可用的場景中,保證併發量的情況下需要使用分布式鎖來做控制,保證應用的可靠性。我們知道jdk提供了一些常用的鎖比如reentrantlock,reentrantreadwritelock,synchronized。對於這些鎖的實現這裡就不詳細介紹了,在使用過程中這些鎖鎖的是物件,在單伺服器...