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);
    }
}
相关推荐
登云时刻1 小时前
Kubernetes集群外连接redis集群和使用redis-shake工具迁移数据(一)
redis·kubernetes·bootstrap
码蜂窝编程官方3 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
AuroraI'ncoding3 小时前
时间请求参数、响应
java·后端·spring
计算机毕设指导66 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
煎饼小狗7 小时前
Redis五大基本类型——Zset有序集合命令详解(命令用法详解+思维导图详解)
数据库·redis·缓存
ExiFengs7 小时前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
瓜牛_gn7 小时前
依赖注入注解
java·后端·spring
秋意钟8 小时前
缓存雪崩、缓存穿透【Redis】
redis
一元咖啡8 小时前
SpringCloud Gateway转发请求到同一个服务的不同端口
spring·spring cloud·gateway
简 洁 冬冬9 小时前
046 购物车
redis·购物车