Redis结合springboot发布消息与订阅处理用户日志埋点

依赖

        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

yml配置

spring:
  redis:
      host: localhost
      port: 6379
      password:
      database: 0
      jedis:
        pool:
          max-idle: 8
          max-active: 8
          max-wait: -1
          min-idle: 0
      timeout: 5000

redis配置:


import io.lettuce.core.ReadFrom;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


/**
 * Redis配置
 *
 * @author Mr Guo
 * @version 1.0
 */
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig {

    @Bean
    @Autowired
    public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.ANY)
                .build();
        RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());
        serverConfig.setPassword(redisProperties.getPassword());
        redisProperties.setDatabase(redisProperties.getDatabase());
        return new LettuceConnectionFactory(serverConfig, clientConfig);
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        RedisTemplate redisTemplate = new RedisTemplate();

        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setStringSerializer(stringSerializer);
        return redisTemplate;
    }
}

消息监听方法

package com.nyjk.union.miniapp.config.redis;

import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.hetianyi.common.Const;
import com.github.hetianyi.common.util.CollectionUtil;
import com.nyjk.union.miniapp.common.model.po.LogDO;
import com.nyjk.union.miniapp.service.LogService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author Mr Guo
 * @version 1.0.0
 * @date 2020/7/21 10:01
 */
@Component
@Slf4j
public class RedisSubEventListener implements MessageListener {

    @Resource
    private LogService logService;

    private List<LogDO> logCache = new ArrayList<>(10);

    @SneakyThrows
    @Override
    public void onMessage(Message message, byte[] pattern) {
        byte[] body = message.getBody();
        byte[] channel = message.getChannel();

        if (body == null || channel == null) {
            log.error("body or channel is null");
            return;
        }

        // 收到订阅消息:"{\"id\":0,\"openId\":\"xxxx\",\"type\":1,\"payload\":\"1\",\"createTime\":\"Jul 21, 2020 10:29:47 AM\"}"
        // TODO 将消息反序列化,并保存到log表


        synchronized (logCache) {
            try {
                LogDO logDO = Const.OBJECT_MAPPER.readValue(new String(body), LogDO.class);
                logCache.add(logDO);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 定时将cache里的日志刷到数据库中
     */
    @Scheduled(initialDelay = 5000, fixedDelay = 10000)
    public void scheduleInsert() {
        if (CollectionUtil.isNullOrEmpty(logCache)) {
            return;
        }

        synchronized (logCache) {
            //TODO service落库,
            logService.saveBatch(logCache);
            logCache.clear();
        }
    }
}

controller层发布消息:

// 频道 + 实体类
 redisTemplate.convertAndSend("channel_log",LogDO.builder()
               .build());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值