我們有時會在網站中看到最後的通路使用者、最近的活躍使用者等等諸如此類的一些資訊。本文就以最後的通路使用者為例,
用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.