我們有時會在網站中看到最后的訪問用戶、最近的活躍用戶等等諸如此類的一些信息。本文就以最后的訪問用戶為例,
用Redis來實現這個小功能。在這之前,我們可以先簡單了解一下在oracle、sqlserver等關系型數據庫中是怎么實現的。
不可否認至少會有一張表來記錄,根據時間desc排序,再取出前幾條數據。下面來看看怎么用Redis來實現這個小功能:
技術 | 說明 |
Redis | 存儲數據,用了主從的模式,主寫從讀 |
artTemplate | 主要是用於顯示最后登陸的5位用戶的名稱 |
簡單的思考:要用Redis的那種數據結構來存儲這些數據呢?我們只要顯示最后的5個訪問用戶(游客不在統計之內),結合
一些數據的操作,個人認為,List是個比較好的選擇。
要記錄下是那個用戶的訪問,必須要有一個登陸的操作控制。
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 }
在處理登陸時,難免會出現這樣的情況,在一段時間內只有1個用戶登陸,而且這個用戶還由於一些原因登陸了多次,所以
我們需要簡單的處理一下,讓我們的List只記錄下最新的那個記錄就好,所以要先把已經存在的先remove掉,然后才把新的記錄
push進去。
接下來就是處理要顯示的信息了。我們需要先知道我們的key中已經有多少個元素(用戶)了,然后根據這個數量來進行不同的
處理:當不足5個的時候,就不用進行ltrim操作,直接取全部數據就好了,超過5個時,就先用ltrim處理一下,再取List中的數據。
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 }
要模擬多個用戶登陸,所以就用了幾個按鈕來模擬,觸發點擊事件就是登陸成功。登陸成功之后自然在更新最近的訪問用戶信
息,所以要在登陸成功的回調函數中去刷新一下訪問用戶的信息。登陸的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 }
下面就是登陸成功的回調函數,取到數據后便向模板中灌數據,然后把根據模板得到的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 }
上面說到的模板,定義是十分簡單的,更多有關於這個模板引擎的信息可以參考這個地址: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>

可以看到,正如我們的預期,只顯示最后登陸的5個用戶的名稱。
再來看看redis里面的數據:
正好應驗了前面說的只保留了最后的5個。
記錄最新的一些日記信息、交易信息等等都是屬於一個大類的,其實對於這一類問題,都是可以用List來處理的,可以來看看
官網的這段話,這段話包含了許多的應用場景。
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.