spring使用redis作为消息订阅

redis可以用于消息订阅,下面一段代码实现了spring中使用redis作为消息订阅模型:

消息处理器:

Java 复制代码
/**
 * 接口RedisMessageHandler:
 */
public interface RedisMessageHandler {

    /**
     * 处理redis消息
     * @param message redis消息
     * @return 处理结果
     */
    String handlerRedisMessage(TMRedisMessage message);

}

实现消息处理:

java 复制代码
@Service
@Slf4j
public class ClusterMessageHandler implements RedisMessageHandler {

    @Override
    public String handlerRedisMessage(TMRedisMessage tmRedisMessage) {

        log.info("收到消息通知,消息内容:{}", tmRedisMessage);

        // 设置JWT信息
        JwtUtil.setJwtInfo(String.valueOf(tmRedisMessage.getAppId()), tmRedisMessage.getUin());

        // 构造集群组件创建/卸载请求
        var clusterRequest = new ClusterRequest();
        clusterRequest.setClusterId(tmRedisMessage.getClusterId());
        
        ClusterFactory.get(ClusterTypeEnum.COMMON.getName()).create(clusterRequest);

        JwtUtil.removeJwtInfo();

        return "success";
    }
}

消息消费者:

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencent.tbds.tm.platform.server.message.RedisMessageHandler;
import com.tencent.tbds.tm.platform.server.message.pojo.TMRedisMessage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 类RedisConsumer:
 */

@Component
@Slf4j
public class RedisConsumer implements MessageListener {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private final Map<String, RedisMessageHandler> redisMessageHandlerMap;

    public RedisConsumer(ConfigurableApplicationContext context) {
        this.redisMessageHandlerMap = context.getBeansOfType(RedisMessageHandler.class);
    }

    @Override
    public void onMessage(Message message, byte[] bytes) {
        try {
            var channel = new String(message.getChannel());
            var body = new String(message.getBody());
            log.info("Received Redis message: {} from channel: {}", body, channel);
            var tmRedisMessage = new ObjectMapper().readValue(body, TMRedisMessage.class);
            var isSet = redisTemplate.opsForValue().setIfAbsent(tmRedisMessage.getClusterType() + tmRedisMessage.getEventsType(), "1", 5, TimeUnit.SECONDS);
            if (isSet != null && isSet) {
                for (var redisMessageHandler : redisMessageHandlerMap.values()) {
                    messageErrorHandler(redisMessageHandler, tmRedisMessage);
                }
            }

        } catch (Exception e) {
            log.error("Received Redis Message From Tm Error! ", e);
        }
    }

    /**
     * 消息处理错误处理
     * @param redisMessageHandler 请求处理类
     * @param tmRedisMessage 消息体
     */
    private void messageErrorHandler(RedisMessageHandler redisMessageHandler, TMRedisMessage tmRedisMessage) {
        var errMessage = "";
        try {
            var handlerClass = redisMessageHandler.getClass();
            var annotation = handlerClass.getAnnotation(MessageHandler.class);
            var clusterType = annotation.ClusterType();
            var eventsType = annotation.EventsType();
            if (clusterType.length == 0 && eventsType.length == 0) {
                log.info("{} Handler all Redis Message", handlerClass.getName());
                errMessage = redisMessageHandler.handlerRedisMessage(tmRedisMessage);
            } else {
                var clusterTypeList = Arrays.stream(clusterType)
                        .boxed()
                        .toList();
                var eventsTypes = Arrays.asList(eventsType);

                if (clusterTypeList.contains(tmRedisMessage.getClusterType()) &&
                        eventsTypes.contains(tmRedisMessage.getEventsType())) {
                    log.info("Invoke RedisMessageHandler to handler Message: {}", handlerClass.getName());
                    errMessage = redisMessageHandler.handlerRedisMessage(tmRedisMessage);
                }
            }
        } catch (Exception e) {
            errMessage = e.getMessage();
        }
        log.info("Redis message handler  result is {}", errMessage);
    }
}
相关推荐
Tatakai252 分钟前
Mybatis Plus分页查询返回total为0问题
java·spring·bug·mybatis
A_cot44 分钟前
Redis 的三个并发问题及解决方案(面试题)
java·开发语言·数据库·redis·mybatis
掐指一算乀缺钱2 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
芊言芊语2 小时前
分布式缓存服务Redis版解析与配置方式
redis·分布式·缓存
bug菌¹2 小时前
滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
spring·spring cloud·gateway
小哇6663 小时前
spring-TransactionTemplate 编程式事务
数据库·spring
攻城狮的梦3 小时前
redis集群模式连接
数据库·redis·缓存
ChinaRainbowSea4 小时前
十三,Spring Boot 中注入 Servlet,Filter,Listener
java·spring boot·spring·servlet·web
小游鱼KF4 小时前
Spring学习前置知识
java·学习·spring
阿乾之铭5 小时前
spring MVC 拦截器
java·spring·mvc