Redis多数据库存储实现用户行为缓存
在我的系统中,为了优化用户行为数据的存储与访问服从,我引入了Redis缓存,并将数据分布在不同的Redis数据库中。通过这种方式,可以淘汰单一数据库的负载,进步系统的整体性能。
紧张实现步骤
- Redis配置
- 配置两个Redis毗连工厂,分别用于存储Token和用户行为数据。
- 创建对应的RedisTemplate实例,指定不同的毗连工厂及序列化方式。
- 用户行为服务
- 通过UserBehaviorService接口及实在现类UserBehaviorServiceImpl,实现对用户点赞、收藏、品评、浏览行为的记录。
- 在操作数据库的同时,将用户行为数据存储到Redis中以进步读取服从。
- Token拦截器
- 使用TokenInterceptor类在每次请求前验证Token。
- 验证通过后,将用户信息存储到ThreadLocal中,供后续操作使用。
代码实现
Redis配置类
- @Configuration
- public class RedisConfig {
- @Value("${spring.data.redis.host}")
- private String redisHost;
- @Value("${spring.data.redis.port}")
- private int redisPort;
- @Value("${spring.data.redis.password}")
- private String redisPassword;
- @Bean(name = "tokenRedisConnectionFactory")
- public RedisConnectionFactory tokenRedisConnectionFactory() {
- RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, redisPort);
- config.setPassword(redisPassword);
- config.setDatabase(0);
- return new LettuceConnectionFactory(config);
- }
- @Bean(name = "userBehaviorRedisConnectionFactory")
- public RedisConnectionFactory userBehaviorRedisConnectionFactory() {
- RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, redisPort);
- config.setPassword(redisPassword);
- config.setDatabase(1);
- return new LettuceConnectionFactory(config);
- }
- @Bean(name = "redisTemplate")
- public StringRedisTemplate redisTemplate(@Qualifier("tokenRedisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
- StringRedisTemplate template = new StringRedisTemplate();
- template.setConnectionFactory(redisConnectionFactory);
- template.setKeySerializer(new StringRedisSerializer());
- template.setValueSerializer(new StringRedisSerializer());
- return template;
- }
- @Bean(name = "userBehaviorRedisTemplate")
- public RedisTemplate<String, Map<String, Integer>> userBehaviorRedisTemplate(@Qualifier("userBehaviorRedisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
- RedisTemplate<String, Map<String, Integer>> template = new RedisTemplate<>();
- template.setConnectionFactory(redisConnectionFactory);
- template.setKeySerializer(new StringRedisSerializer());
- template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Map.class));
- return template;
- }
- }
复制代码 用户行为服务实现类
- @Service
- public class UserBehaviorServiceImpl implements UserBehaviorService {
- private static final long CACHE_EXPIRATION_DAYS = 1;
- private static final String CACHE_PREFIX = "articleCounts:";
- @Autowired
- private UserBehaviorMapper userBehaviorMapper;
- @Autowired
- @Qualifier("userBehaviorRedisTemplate")
- private RedisTemplate<String, Map<String, Integer>> userBehaviorRedisTemplate;
- @Override
- public void setLikeArticle(Likes likes) {
- likes.setCreateTime(LocalDateTime.now());
- Integer userId = ThreadLocalUtil.getUser("id");
- if (userId != null) {
- likes.setUserId(userId);
- }
- userBehaviorMapper.insertLike(likes);
- }
- @Override
- public void setFavoriteArticle(Favorites favorites) {
- favorites.setCreateTime(LocalDateTime.now());
- Integer userId = ThreadLocalUtil.getUser("id");
- if (userId != null) {
- favorites.setUserId(userId);
- }
- userBehaviorMapper.insertFavorite(favorites);
- }
- @Override
- public void setCommentArticle(Comments comments) {
- comments.setCreateTime(LocalDateTime.now());
- Integer userId = ThreadLocalUtil.getUser("id");
- if (userId != null) {
- comments.setUserId(userId);
- }
- userBehaviorMapper.insertComment(comments);
- }
- @Override
- public void setViewArticle(Views views) {
- views.setCreateTime(LocalDateTime.now());
- Integer userId = ThreadLocalUtil.getUser("id");
- if (userId != null) {
- views.setUserId(userId);
- }
- userBehaviorMapper.insertView(views);
- }
- @Override
- public Map<String, Integer> getArticleCounts(Integer articleId) {
- String key = CACHE_PREFIX + articleId;
- Map<String, Integer> counts = userBehaviorRedisTemplate.opsForValue().get(key);
- if (counts == null) {
- counts = fetchArticleCountsFromDB(articleId);
- cacheArticleCounts(articleId, counts);
- }
- return counts;
- }
- private Map<String, Integer> fetchArticleCountsFromDB(Integer articleId) {
- Map<String, Integer> counts = new HashMap<>();
- counts.put("likesCount", userBehaviorMapper.selectLikesCount(articleId));
- counts.put("favoritesCount", userBehaviorMapper.selectFavoritesCount(articleId));
- counts.put("commentsCount", userBehaviorMapper.selectCommentsCount(articleId));
- counts.put("viewsCount", userBehaviorMapper.selectViewsCount(articleId));
- return counts;
- }
- private void cacheArticleCounts(Integer articleId, Map<String, Integer> counts) {
- String key = CACHE_PREFIX + articleId;
- userBehaviorRedisTemplate.opsForValue().set(key, counts, CACHE_EXPIRATION_DAYS, TimeUnit.DAYS);
- }
- }
复制代码 Token拦截器
- @Component
- public class TokenInterceptor implements HandlerInterceptor {
- @Autowired
- private StringRedisTemplate redisTemplate;
- @Override
- public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
- String token = request.getHeader("Authorization");
- if (token == null || token.isEmpty()) {
- response.setStatus(HttpStatus.UNAUTHORIZED.value());
- return false;
- }
- try {
- ValueOperations<String, String> operations = redisTemplate.opsForValue();
- String redisToken = operations.get(token);
- if (redisToken == null) {
- response.setStatus(HttpStatus.UNAUTHORIZED.value());
- return false;
- }
- Map<String, Object> claims = JwtUtil.parseToken(token);
- ThreadLocalUtil.setUser(claims);
- return true;
- } catch (Exception e) {
- response.setStatus(HttpStatus.UNAUTHORIZED.value());
- return false;
- }
- }
- @Override
- public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
- }
- @Override
- public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) throws Exception {
- ThreadLocalUtil.remove();
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |