项目启动时自动订阅配置中指定的MQ主题,并将接收到的消息存储在Redis中,提供了一个HTTP接口来查询存储的消息

涵盖从application.yml配置,通过MQ订阅消息,将消息存放到Redis,最后通过HTTP接口提供消息查询的整个流程,我们将分步进行。

Step 1: application.yml配置

yaml 复制代码
spring:
  profiles:
    active: dev

  redis:
    host: localhost
    port: 6379
    database: 0
    jedis:
      pool:
        max-active: 10
        max-idle: 5
        min-idle: 0
        max-wait: -1ms

mq:
  subscribe:
    enable: true
    topics:
      - topic1
      - topic2
    tag: "*"
    consumerGroup: "yourConsumerGroup"

这个配置文件定义了Redis的连接信息和MQ订阅的相关配置,包括是否启动时自动订阅MQ和订阅的主题列表。

Step 2: 消息存储服务(MessageStorage)

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Map;

@Service
public class MessageStorage {
    private final StringRedisTemplate redisTemplate;

    @Autowired
    public MessageStorage(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void storeMessage(String topic, String messageId, String message) {
        redisTemplate.opsForHash().put("mq:topic:" + topic, messageId, message);
    }

    public String getMessageByTopicAndId(String topic, String messageId) {
        Object message = redisTemplate.opsForHash().get("mq:topic:" + topic, messageId);
        return message != null ? message.toString() : null;
    }

    public Map<Object, Object> getAllMessagesByTopic(String topic) {
        return redisTemplate.opsForHash().entries("mq:topic:" + topic);
    }
}

Step 3: ConsumerManager

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

@Service
public class ConsumerManager implements CommandLineRunner {

    @Value("${mq.subscribe.enable:false}")
    private boolean autoSubscribe;

    @Value("${mq.subscribe.topics}")
    private List<String> topics;

    @Value("${mq.subscribe.tag}")
    private String tag;

    @Value("${mq.subscribe.consumerGroup}")
    private String consumerGroup;

    @Autowired
    private MessageStorage messageStorage;

    // 示例方法,需根据实际MQ客户端进行实现
    public void startConsumer(String topic, String tag, String consumerGroup) {
        // 假设的MQ订阅逻辑
        // 省略实际的MQ订阅代码
        // 假设收到消息后:
        String messageId = "uniqueMessageId"; // 假设的消息ID
        String message = "Example Message"; // 假设的消息内容
        messageStorage.storeMessage(topic, messageId, message);
    }

    @Override
    public void run(String... args) {
        if (autoSubscribe) {
            topics.forEach(topic -> {
                try {
                    startConsumer(topic, tag, consumerGroup);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

Step 4: ConsumerController(HTTP接口)

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api/messages")
public class ConsumerController {

    @Autowired
    private MessageStorage messageStorage;

    @GetMapping("/get")
    public ResponseEntity<?> getMessage(@RequestParam String topic, @RequestParam(required = false) String messageId) {
        if (messageId != null) {
            String message = messageStorage.getMessageByTopicAndId(topic, messageId);
            return message != null ? ResponseEntity.ok(message) : ResponseEntity.notFound().build();
        } else {
            Map<Object, Object> messages = messageStorage.getAllMessagesByTopic(topic);
            return ResponseEntity.ok(messages);
        }
    }
}

说明

  • MQ订阅逻辑 :ConsumerManager中的startConsumer方法需要根据你使用的MQ客户端库具体实现,这里仅提供了一个概念性的示例。
  • 消息存储与检索 :MessageStorage类使用Redis的Hash数据结构

来存储和检索消息。每个topic对应一个Hash,其中每个messageId是键,消息内容是值。

  • HTTP接口 :ConsumerController提供了一个/api/messages/get接口,允许根据topic和可选的messageId查询消息。

通过上述步骤,我们完成了一个简单的系统,它能够在项目启动时自动订阅配置中指定的MQ主题,并将接收到的消息存储在Redis中。同时,我们也提供了一个HTTP接口来查询存储的消息。这个示例提供了一个基本框架,你可以根据实际的需求和MQ客户端库进行调整和扩展。

相关推荐
Yves..15 分钟前
HTTP 协议学习笔记:从报文结构到抓包实践
网络协议·http·fiddler
沫璃染墨38 分钟前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Session
linux·服务器·c++·tcp/ip·ubuntu·http·交互
温暖小土39 分钟前
在 CentOS 上安装 Redis Stack
linux·redis·centos
CCIE-Yasuo1 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶1 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构
涛思数据(TDengine)1 小时前
从工业本体到 AI 原生:TDengine 出席 2026 QCon 分享工业数据基础设施路径
大数据·数据库·人工智能·tdengine·工业
Jesse_EC2 小时前
换乘次数最少的路径 SQL 查询详解与实战经验——从 WITH RECURSIVE 到 pgRouting
数据库·postgresql
工控丫丫2 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
这个DBA有点耶3 小时前
云数据库半夜卡顿,CPU才30%?深挖云盘IOPS突发限制与内核挂起机制
数据库·mysql·云原生
Mikko74 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端