一,功能背景
領導偶然間問起我們的考核系統使用情況如何,最近考慮下做個活躍用戶統計功能
二,功能設計
針對性能上要求實時統計,用戶名都為8位數字等特點,擬采用redis方案:
使用bitmap,用戶登錄的同時,將用戶所在的位置為1
三,代碼
1,直接上代碼
public void setUserActive(Integer id) { Date currentTime = new Date(); String currentStr = new SimpleDateFormat("yyyy-MM-dd").format(currentTime); String key = "login:"+currentStr; try { cluster.setbit(key, id, true); } catch (Exception e) { log.error("登錄激活用戶計數出錯:"+id+","+e); } }
用戶登錄的功能模塊調用該方法,bitmap按照日期創建,即每天創建一個,垃圾回收委托給redis的GC機制。
行內用戶是8位數字,所以支持千萬級的用戶統計,經測試,性能較好。如果用戶名非數字,可以通過哈希算法轉換,本人暫未測試。
2,統計
public long getActiveUserCount(int period) { Date currentTime = new Date(); long bitCount = 0; SimpleDateFormat sf = new SimpelDateFormat("yyyy-MM-dd"); try { for (int i = 0; i < period; i++) { //獲得前一天的日期 String currentStr = sf.format(currentTime); String key = "login:" + currentStr; //獲得這一天日期的活躍用戶字節數組 bitCount += cluster.bitcount(key, 1, 99999999); currentTime = DateUtils.addDays(currentTime, -1); } } catch (Exception e) { log.error("查詢"+day+"天內活躍用戶出錯!"+e); return 0; } //統計人數 return bitCount; }
其中period指統計周期,我統計的是一周,傳參為7,
bicount方法后兩位參數是start和end,在該范圍內統計1的個數。這樣就實現了活躍用戶統計
