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);
    }
}
相关推荐
我可能是个假开发5 小时前
FTP Unicode 文件名导致 `550` 的问题分析与解决方案
java·开发语言·spring
前端兰博5 小时前
05-Redis
redis·后端
OnlineProxy6 小时前
亚马逊多账号运营:如何在规避“关联封号”风险的同时实现电商规模化扩张
服务器·数据库·redis
【JAVA】玩家6 小时前
Spring核心原理全解析:从零到生产实战
java·后端·spring
ShineWinsu11 小时前
对于Redis:主从复制的解析
linux·数据库·c++·redis·缓存·面试·主从复制
打工仔折腾 AI13 小时前
System Prompt 替代 Few-shot:用规则约束大模型输出的省钱实践
java·人工智能·python·spring·langchain·prompt·ai agent 实战
ShineWinsu14 小时前
对于Redis:事务的解析
数据库·redis·mysql·缓存·面试·事务·acid
夕除16 小时前
redis--OpenResty
java·redis
开开心心就好17 小时前
视频压缩工具推荐,绿色版免安装双击即用
java·前端·人工智能·spring·智能手机·intellij-idea·excel
专业程序开发源17 小时前
springboot古城景区管理系统88564-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计