最近公司做了一個類似 於發帖,交友圈一個這樣的功能 在如何精確快速的獲取用戶的瀏覽量,且及時的更新顯示,最初我是這樣想,把每條帖子內容瀏覽量放到reids 里面,但是redis只是用來存零時數據,想想覺的還是放表里面好,在發布的帖子表增加一個字段作為該帖子的瀏覽量,但是每次從表里面讀更新瀏覽量,這樣肯定是不明智的做法,直接看下面代碼
1:當用戶瀏覽帖子內容時 根據KEY 從redis 獲取改帖子的瀏覽量如果存在,那么就在以前的基礎上+1 否則就從數據庫查詢出來再+1然后放到緩存里面
// 瀏覽量 if (redisClient.hexists(CAMPUS_CIRCLE_PAGEVIEWS_KEY, id.toString())) { redisClient.hincrBy(CAMPUS_CIRCLE_PAGEVIEWS_KEY, id.toString(), 1); } else { Integer count = campusCircle.getCount() + 1; redisClient.hincrBy(CAMPUS_CIRCLE_PAGEVIEWS_KEY, id.toString(), count); }
CAMPUS_CIRCLE_PAGEVIEWS_KEY 這個是帖子瀏覽量的key
id.toString()是帖子ID
2:寫一個定時任務 每10 分鍾同步到數據庫里面 這個根據業務需求,20分鍾30 隨便你
/** * 定時任務 * * @author ckj * */ @Component public class CampusCircleTask { private static final Logger LOGGER = LoggerFactory.getLogger(CampusCircleTask.class); @Autowired private CampusCircleDao campusCircleDao; @Autowired private RedisClient redisClient; private static final String CAMPUS_CIRCLE_PAGEVIEWS_KEY = "campus:circle:pageviews";// 校園圈瀏覽量 @Scheduled(cron="0 0/10 * * * *") public void synchronizePageviews() { LOGGER.info("CampusCircleTask start"); Map<String, String> map = redisClient.hgetAll(CAMPUS_CIRCLE_PAGEVIEWS_KEY); for (Map.Entry<String, String> entry : map.entrySet()) { CampusCircle campusCircle = campusCircleDao.getById(Integer.parseInt(entry.getKey())); campusCircle.setCount(Integer.parseInt(entry.getValue())); campusCircleDao.update(campusCircle); } LOGGER.info("CampusCircleTask end"); } }
3:頁面顯示的時候 由於我們存到redis是 Hash 形式的,這時可要遍歷Hash 獲取
/** * 從redids 獲取 瀏覽量 * * @param campusCircleId 帖子ID * @return */ public Integer getPageviews(Integer campusCircleId) { Integer count = 0; Map<String, String> map = redisClient.hgetAll(CAMPUS_CIRCLE_PAGEVIEWS_KEY); for (Map.Entry<String, String> entry : map.entrySet()) { if (campusCircleId.toString().equals(entry.getKey())) { count = Integer.parseInt(entry.getValue()); break; } } return count; }