手把手教你使用 Java 和 Redis 實現排行榜!

編輯:業餘草 來源:https://www.xttblog.com/?p=4937

前言

排行榜作為互聯網應用中幾乎必不可少的一個元素,其能夠勾起人類自身對比的慾望,從而來增加商品的銷量。排行榜的實現方式基本大同小異,大部分都基於 Redis 的有序集合 sorted set 來實現。不久前,負責開發一個活動,就有排行榜這個需求,筆者也使用 Redis 進行了實現。本文通過了商品銷售排行榜這一模型,來進行演示。

需求

  1. 按照商品銷量進行排行
  2. 可以獲得指定商品的排名
  3. 顯示實時銷售動態情況

需求分析

分析需求,以上這些都可以通過 Redis 的有序集合相關命令進行實現,首先看一下使用到的具體 Redis 命令。

redis> ZADD bangdan 1 "one"  (integer) 1  # 對有序集合中指定成員的分數加上增量  redis> zadd bangdan 1 "one" 4 "three" 3 "two"  (integer) 2  # 將一個或多個成員以及分數加入到有序集合中  redis> zrange bangdan 0 1  1) "one"  2) "three"  # 按照 score 升序排列 ,取出前兩名  redis> zscore bangdan three  "4"  # 獲得榜單中指定元素的score  redis> zrank bangdan one  (integer) 0  # 在升序榜中的名次 第一返回0  # 第三個需求需要使用 Redis 的 list 來進行實現  redis> LPUSH dynamic abc  (integer) 1  # 向隊列左側頭部 push 數據  redis> LINDEX dynamic 0  "abc"  # 通過索引獲取列表中的元素  redis> LTRIM dynamic 0 2  "abc"  # 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除

排行榜預覽

按照需求開發,最後的效果如下:

下面我們通過 Java 實現它!

引入依賴

項目中使用到了 Redis,因此需要引入相關依賴,為了簡明演示,這裡沒有使用 JedisPool。

<dependency>      <groupId>redis.clients</groupId>      <artifactId>jedis</artifactId>      <version>2.7.3</version>  </dependency>

主要程式碼

1、頁面上點擊一次購買按鈕,則對該手機的銷量加 1,同時將銷售動態添加到隊列當中。

jedis.zincrby(Constants.SALES_LIST, 1, String.valueOf(phoneId));  jedis.lpush(Constants.BUY_DYNAMIC, msg);

2、獲得排行榜。

// 按照scope升序排名,取出前五  jedis.zrevrangeWithScores(Constants.SALES_LIST, 0, 4);

3、獲得指定手機的排名情況。

jedis.zrevrank(Constants.SALES_LIST, String.valueOf(phoneId));

4、獲得銷售動態,此處只取 3 條,同時隊列只保存最新的 20 條動態。

List<DynamicVO> dynamicList = new ArrayList<>();  for (int i = 0; i < 3; i++) {          String result = jedis.lindex(Constants.BUY_DYNAMIC, i);          if (StringUtils.isEmpty(result)) {              break;          }          String[] arr = result.split(Constants.separator);          long time = Long.valueOf(arr[0]);          String phone = arr[1];          DynamicVO vo = new DynamicVO();          vo.setPhone(phone);          vo.setTime(StringUtil.showTime(new Date(time)));          dynamicList.add(vo);  }  jedis.ltrim(Constants.BUY_DYNAMIC, 0, 19);

5、因為排行榜這種實時性比較強的數據,更新比較快,個人覺得沒有必要進行持久化,如果 Redis 的排行榜數據丟失,可以通過程式碼重新計算排行,通過 zadd 命令,重新添加到 Redis 中即可。

Map<String, Double> map = new HashMap<>();      map.put("1", 4.0);      map.put("2", 2.0);      map.put("3", 3.0);  jedis.zadd(Constants.SALES_LIST, map);

上面是主要的實現程式碼,還有不少細節需要完善。