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);
    }
}
相关推荐
夕除37 分钟前
redis--015
redis
Bs_MoneyMagnet1 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计
迷茫的大专生4 小时前
高可用总结
redis·mysql·nginx·高可用
辉灰笔记6 小时前
Redis6.0.10升级迁移至Redis7.4.6(修复CVE‑2025‑49844,业务无需重启)
redis·redis7·漏洞修复·数据库迁移·redis平滑升级·cve-2025-49844
步行cgn7 小时前
Spring 底层如何创建对象:反射机制与实例化策略
java·后端·spring
sdm0704278 小时前
Linux 中安装 Redis 5
redis
步行cgn9 小时前
Spring 注入 null 和空字符串详解
数据库·spring·oracle
草莓熊Lotso9 小时前
【Redis 进阶】主从复制深度解析:从配置落地到 PSYNC 同步原理
linux·开发语言·网络·数据库·redis·缓存·php
Wang's Blog10 小时前
Java框架快速入门: Spring Security+OAuth2之单点登录(SSO)实战
服务器·spring·状态模式
譕痕10 小时前
Idea 集成 智能体开发工具“千问(qwen)”
java·ide·spring·语言模型