<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近遇到一個比較緊急的任務,要求統計線上使用者,目的是配合效能測評,要求證明自己系統的線上使用者能夠達標,不過系統因為歷史原因,並沒有這個功能,所以只能去springSession官網和網上搜資料,想到通過統計redis裡快取的資料
因為系統原先的邏輯是使用Spring Session加上Redis做的對談共用實現的單點登入,登入之後會在session設定一個key值表示使用者已經登入過,同時重寫HttpServletRequestWrapper 設定remoteUser資料值
class RemoteUserRequestWrapper extends HttpServletRequestWrapper { String userCode; RemoteUserRequestWrapper(HttpServletRequest request) { super(request); this.userCode = (String) request.getSession() .getAttribute(org.apache.commons.lang3.StringUtils.isBlank(sessionKeyName)?DEFAULT_SESSION_KEY_NAME:sessionKeyName); } @Override public String getRemoteUser() { return userCode; } }
Spring Session快取在redis裡的資料
這個ssoLoginUser
key是自己登入時候設定的,根據業務修改,經過測試,在登出系統時候,session設定過期獲取removeAttribute不能清redis裡的key資料,所以只能在登出系統邏輯加上:
Set<String> keys = RedisUtils.redisTemplate.keys("spring:session:sessions:*"); for(String key : keys){ if(key.indexOf("expires")==-1){ String s = (String)RedisUtils.redisTemplate.opsForHash().get(key, "sessionAttr:ssoLoginUser"); if(request.getRemoteUser().equals(s)) { logger.info("loginusername:{}",s) RedisUtils.redisTemplate.opsForHash().delete(key, "sessionAttr:ssoLoginUser"); } } }
進行資料統計:
List<Map<String,Object>> list = new ArrayList<Map<String, Object>>(); List<Map<String,Object>> data = new ArrayList<Map<String, Object>>(); Set<String> keys = redisTemplate.keys("spring:session:sessions:*"); for(String key : keys){ if(key.indexOf("expires")==-1){ String s = (String)redisTemplate.opsForHash().get(key, "sessionAttr:ssoLoginUser"); if(StringUtils.isNotBlank(s)) { System.out.println(s); Map<String,Object> map = new HashMap<String,Object>(16); map.put("usercode", s); list.add(map); } } } return list;
pom.xml:
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.2.2.RELEASE</version> <type>pom</type> </dependency> <dependency> <groupId>biz.paluch.redis</groupId> <artifactId>lettuce</artifactId> <version>3.5.0.Final</version> </dependency>
RedisUtils.java:
package com.common.utils.redis; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebApplicationContext; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; public class RedisUtils { private RedisUtils() { } @SuppressWarnings("unchecked") public static RedisTemplate<String, Object> redisTemplate = ContextLoader.getCurrentWebApplicationContext().getBean(RedisTemplate.class); /** * 設定有效時間 * * @param key Redis鍵 * @param timeout 超時時間 * @return true=設定成功;false=設定失敗 */ public static boolean expire(final String key, final long timeout) { return expire(key, timeout, TimeUnit.SECONDS); } /** * 設定有效時間 * * @param key Redis鍵 * @param timeout 超時時間 * @param unit 時間單位 * @return true=設定成功;false=設定失敗 */ public static boolean expire(final String key, final long timeout, final TimeUnit unit) { Boolean ret = redisTemplate.expire(key, timeout, unit); return ret != null && ret; } /** * 刪除單個key * * @param key 鍵 * @return true=刪除成功;false=刪除失敗 */ public static boolean del(final String key) { redisTemplate.delete(key); return true; } /** * 刪除多個key * * @param keys 鍵集合 * @return 成功刪除的個數 */ public static long del(final Collection<String> keys) { redisTemplate.delete(keys); return 0; } /** * 存入普通物件 * * @param key Redis鍵 * @param value 值 */ public static void set(final String key, final Object value) { redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES); } // 儲存普通物件操作 /** * 存入普通物件 * * @param key 鍵 * @param value 值 * @param timeout 有效期,單位秒 */ public static void set(final String key, final Object value, final long timeout) { redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS); } /** * 獲取普通物件 * * @param key 鍵 * @return 物件 */ public static Object get(final String key) { return redisTemplate.opsForValue().get(key); } // 儲存Hash操作 /** * 往Hash中存入資料 * * @param key Redis鍵 * @param hKey Hash鍵 * @param value 值 */ public static void hPut(final String key, final String hKey, final Object value) { redisTemplate.opsForHash().put(key, hKey, value); } /** * 往Hash中存入多個資料 * * @param key Redis鍵 * @param values Hash鍵值對 */ public static void hPutAll(final String key, final Map<String, Object> values) { redisTemplate.opsForHash().putAll(key, values); } /** * 獲取Hash中的資料 * * @param key Redis鍵 * @param hKey Hash鍵 * @return Hash中的物件 */ public static Object hGet(final String key, final String hKey) { return redisTemplate.opsForHash().get(key, hKey); } /** * 獲取多個Hash中的資料 * * @param key Redis鍵 * @param hKeys Hash鍵集合 * @return Hash物件集合 */ public static List<Object> hMultiGet(final String key, final Collection<Object> hKeys) { return redisTemplate.opsForHash().multiGet(key, hKeys); } // 儲存Set相關操作 /** * 往Set中存入資料 * * @param key Redis鍵 * @param values 值 * @return 存入的個數 */ public static long sSet(final String key, final Object... values) { Long count = redisTemplate.opsForSet().add(key, values); return count == null ? 0 : count; } /** * 刪除Set中的資料 * * @param key Redis鍵 * @param values 值 * @return 移除的個數 */ public static long sDel(final String key, final Object... values) { Long count = redisTemplate.opsForSet().remove(key, values); return count == null ? 0 : count; } // 儲存List相關操作 /** * 往List中存入資料 * * @param key Redis鍵 * @param value 資料 * @return 存入的個數 */ public static long lPush(final String key, final Object value) { Long count = redisTemplate.opsForList().rightPush(key, value); return count == null ? 0 : count; } /** * 往List中存入多個資料 * * @param key Redis鍵 * @param values 多個資料 * @return 存入的個數 */ public static long lPushAll(final String key, final Collection<Object> values) { Long count = redisTemplate.opsForList().rightPushAll(key, values); return count == null ? 0 : count; } /** * 往List中存入多個資料 * * @param key Redis鍵 * @param values 多個資料 * @return 存入的個數 */ public static long lPushAll(final String key, final Object... values) { Long count = redisTemplate.opsForList().rightPushAll(key, values); return count == null ? 0 : count; } /** * 從List中獲取begin到end之間的元素 * * @param key Redis鍵 * @param start 開始位置 * @param end 結束位置(start=0,end=-1表示獲取全部元素) * @return List物件 */ public static List<Object> lGet(final String key, final int start, final int end) { return redisTemplate.opsForList().range(key, start, end); } }
ok,本部落格只能學習參考,因為只是要給客戶一些線上使用者的證明而已,這個臨時的統計不能用於生產,要做比較齊全的線上使用者統計,需要花多點時間,有問題希望能指出。ok,簡單記錄一下,方便之後自己回顧
到此這篇關於SpringSession通過Redis統計線上使用者數量的文章就介紹到這了,更多相關Redis線上使用者數量內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45