Redis简单案例(二) 网站最近的访问用户
我們有時(shí)會(huì)在網(wǎng)站中看到最后的訪問(wèn)用戶、最近的活躍用戶等等諸如此類的一些信息。本文就以最后的訪問(wèn)用戶為例,
用Redis來(lái)實(shí)現(xiàn)這個(gè)小功能。在這之前,我們可以先簡(jiǎn)單了解一下在oracle、sqlserver等關(guān)系型數(shù)據(jù)庫(kù)中是怎么實(shí)現(xiàn)的。
不可否認(rèn)至少會(huì)有一張表來(lái)記錄,根據(jù)時(shí)間desc排序,再取出前幾條數(shù)據(jù)。下面來(lái)看看怎么用Redis來(lái)實(shí)現(xiàn)這個(gè)小功能:
案例用到的一些相關(guān)技術(shù)和說(shuō)明:| 技術(shù) | 說(shuō)明 |
| Redis | 存儲(chǔ)數(shù)據(jù),用了主從的模式,主寫從讀 |
| artTemplate | 主要是用于顯示最后登陸的5位用戶的名稱 |
簡(jiǎn)單的思考:要用Redis的那種數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)這些數(shù)據(jù)呢?我們只要顯示最后的5個(gè)訪問(wèn)用戶(游客不在統(tǒng)計(jì)之內(nèi)),結(jié)合
一些數(shù)據(jù)的操作,個(gè)人認(rèn)為,List是個(gè)比較好的選擇。?
要記錄下是那個(gè)用戶的訪問(wèn),必須要有一個(gè)登陸的操作控制。
1 /// <summary> 2 /// simulating user login 3 /// </summary> 4 /// <param name="name"></param> 5 /// <returns></returns> 6 [HttpPost("/login")] 7 public IActionResult Login(string name) 8 { 9 if (!string.IsNullOrWhiteSpace(name)) 10 { 11 //Distinct 12 var tran = _redis.GetTransaction(); 13 tran.ListRemoveAsync(_key, name, 1); 14 tran.ListLeftPushAsync(_key, name); 15 tran.Execute(); 16 17 var json = new { code="000",msg= string.Format("{0} login successfully",name) }; 18 return Json(json); 19 } 20 else 21 { 22 var json = new { code = "001", msg = "name can't be empty" }; 23 return Json(json); 24 } 25 }在處理登陸時(shí),難免會(huì)出現(xiàn)這樣的情況,在一段時(shí)間內(nèi)只有1個(gè)用戶登陸,而且這個(gè)用戶還由于一些原因登陸了多次,所以
我們需要簡(jiǎn)單的處理一下,讓我們的List只記錄下最新的那個(gè)記錄就好,所以要先把已經(jīng)存在的先remove掉,然后才把新的記錄
push進(jìn)去。
接下來(lái)就是處理要顯示的信息了。我們需要先知道我們的key中已經(jīng)有多少個(gè)元素(用戶)了,然后根據(jù)這個(gè)數(shù)量來(lái)進(jìn)行不同的
處理:當(dāng)不足5個(gè)的時(shí)候,就不用進(jìn)行l(wèi)trim操作,直接取全部數(shù)據(jù)就好了,超過(guò)5個(gè)時(shí),就先用ltrim處理一下,再取List中的數(shù)據(jù)。
1 /// <summary> 2 /// get the last 5 login user 3 /// </summary> 4 /// <returns></returns> 5 [HttpGet("/login/last")] 6 public IActionResult GetLastFiveLoginUser() 7 { 8 var len = _redis.LLen(_key); 9 if (len > _loginUserAmount) 10 { 11 //limit the count 12 _redis.LTrim(_key, 0, _loginUserAmount-1); 13 } 14 var list = (from i in _redis.LRange(_key, 0, -1) select i.ToString()); 15 16 var json = new { code="000",msg="ok",data = list }; 17 return Json(json); 18 } 到這里,我們的后臺(tái)邏輯已經(jīng)實(shí)現(xiàn)了,下面就是前臺(tái)的展示了。要模擬多個(gè)用戶登陸,所以就用了幾個(gè)按鈕來(lái)模擬,觸發(fā)點(diǎn)擊事件就是登陸成功。登陸成功之后自然在更新最近的訪問(wèn)用戶信
息,所以要在登陸成功的回調(diào)函數(shù)中去刷新一下訪問(wèn)用戶的信息。登陸的function如下:
1 function login(name) { 2 $.ajax({ 3 url: "/login", 4 data: { "name": name }, 5 dataType: "json", 6 method: "POST", 7 success: function (res) { 8 if (res.code == "000") { 9 getLastFiveLoginUser(); 10 } else { 11 console.log(res.msg); 12 } 13 } 14 }); 15 }下面就是登陸成功的回調(diào)函數(shù),取到數(shù)據(jù)后便向模板中灌數(shù)據(jù),然后把根據(jù)模板得到的html放到id為lastLoginUser的div中。
具體代碼如下:
1 function getLastFiveLoginUser() { 2 $.ajax({ 3 url: "/login/last", 4 data: {}, 5 dataType: "json", 6 success: function (res) { 7 if (res.code == "000") { 8 var html = template('lastLoginUserTpl', res); 9 $("#lastLoginUser").html(html); 10 } 11 } 12 }); 13 }上面說(shuō)到的模板,定義是十分簡(jiǎn)單的,更多有關(guān)于這個(gè)模板引擎的信息可以參考這個(gè)地址:https://github.com/aui/artTemplate
下面是模板的具體代碼: 1 <script id="lastLoginUserTpl" type="text/html"> 2 <ul> 3 {{each data as item}} 4 <li> 5 {{item}} 6 </li> 7 {{/each}} 8 </ul> 9 </script>?
好了,到這里是前后臺(tái)都處理好了,下面來(lái)看看效果:可以看到,正如我們的預(yù)期,只顯示最后登陸的5個(gè)用戶的名稱。
再來(lái)看看redis里面的數(shù)據(jù):
正好應(yīng)驗(yàn)了前面說(shuō)的只保留了最后的5個(gè)。
記錄最新的一些日記信息、交易信息等等都是屬于一個(gè)大類的,其實(shí)對(duì)于這一類問(wèn)題,都是可以用List來(lái)處理的,可以來(lái)看看
官網(wǎng)的這段話,這段話包含了許多的應(yīng)用場(chǎng)景?!?/p>
This pair of commands will push a new element on the list, while making sure that the list will not grow larger
than 100 elements. This is very useful when using Redis to store logs for example. It is important to note that
when used in this way LTRIM is an O(1) operation because in the average case just one element is removed from
the tail of the list.
總結(jié)
以上是生活随笔為你收集整理的Redis简单案例(二) 网站最近的访问用户的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: String是值传递还是引用传递
- 下一篇: Nancy简单实战之NancyMusic