Forráskód Böngészése

MQ测试连通性

liudongzhi 1 hónapja
szülő
commit
cf44868f2d

+ 174 - 0
alien-config/RabbitMQ测试说明.md

@@ -0,0 +1,174 @@
+# RabbitMQ 测试说明
+
+## 测试步骤
+
+### 1. 启动应用
+确保应用已启动,并且 RabbitMQ 服务器(120.26.186.130:5672)可以正常连接。
+
+### 2. 检查连接状态
+访问以下接口检查 RabbitMQ 连接是否正常:
+
+```
+GET http://your-host:port/rabbitmq/test/connection/status
+```
+
+**预期结果**:
+- 返回 `{"success": true, "message": "RabbitMQ 连接正常"}`
+- 日志中应该看到 "RabbitMQ 连接工厂配置完成" 和 "RabbitTemplate 配置完成"
+
+### 3. 测试发送订单消息
+发送订单消息到订单队列:
+
+```
+POST http://your-host:port/rabbitmq/test/send/order?message=测试订单123
+```
+
+**预期结果**:
+- 接口返回成功
+- 日志中应该看到:
+  - "消息发送成功到交换机"(确认回调)
+  - "收到订单队列消息"(监听器接收消息)
+
+### 4. 测试发送用户通知消息
+发送用户通知消息:
+
+```
+POST http://your-host:port/rabbitmq/test/send/user-notice?message=测试用户通知
+```
+
+**预期结果**:
+- 接口返回成功
+- 日志中应该看到:
+  - "消息发送成功到交换机"
+  - "收到用户通知队列消息"
+
+### 5. 测试消息返回机制
+发送一个无法路由的消息(测试返回回调):
+
+```
+POST http://your-host:port/rabbitmq/test/send/test-return?message=测试返回
+```
+
+**预期结果**:
+- 接口返回成功
+- 日志中应该看到:
+  - "消息被退回"(返回回调被触发)
+  - 包含 Exchange、RoutingKey、ReplyCode 等信息
+
+### 6. 测试发送字符串消息
+发送简单的字符串消息:
+
+```
+POST http://your-host:port/rabbitmq/test/send/string?message=Hello RabbitMQ
+```
+
+**预期结果**:
+- 消息成功发送并被监听器接收
+
+## 验证要点
+
+### ✅ 连接验证
+- [ ] 应用启动时日志显示 "RabbitMQ 连接工厂配置完成"
+- [ ] 连接状态检查接口返回成功
+
+### ✅ 消息发送验证
+- [ ] 发送消息后,确认回调日志显示 "消息发送成功到交换机"
+- [ ] 接口返回 `{"success": true}`
+
+### ✅ 消息接收验证
+- [ ] 监听器日志显示 "收到订单队列消息" 或 "收到用户通知队列消息"
+- [ ] 消息内容正确显示
+
+### ✅ 返回机制验证
+- [ ] 发送无法路由的消息后,日志显示 "消息被退回"
+- [ ] 包含完整的退回信息(Exchange、RoutingKey、ReplyCode 等)
+
+## 常见问题排查
+
+### 问题1:连接失败
+**症状**:启动时报错,无法连接到 RabbitMQ
+
+**排查**:
+1. 检查 RabbitMQ 服务器是否运行:`telnet 120.26.186.130 5672`
+2. 检查用户名密码是否正确(guest/guest)
+3. 检查虚拟主机是否正确(/)
+4. 检查防火墙是否开放 5672 端口
+
+### 问题2:消息发送成功但监听器未收到
+**症状**:发送消息成功,但监听器没有日志
+
+**排查**:
+1. 检查队列是否已创建(应用启动时会自动创建)
+2. 检查路由键是否正确匹配
+3. 检查监听器是否启用(需要 `@EnableRabbit` 注解)
+4. 查看是否有异常日志
+
+### 问题3:消息被退回
+**症状**:日志显示 "消息被退回"
+
+**原因**:
+- 路由键不匹配
+- 队列不存在
+- 交换机配置错误
+
+**解决**:
+- 检查路由键是否正确
+- 确保队列已创建
+- 检查绑定关系是否正确
+
+## 使用 Postman 或 curl 测试
+
+### curl 示例
+
+```bash
+# 1. 检查连接状态
+curl -X GET http://localhost:8080/rabbitmq/test/connection/status
+
+# 2. 发送订单消息
+curl -X POST "http://localhost:8080/rabbitmq/test/send/order?message=测试订单"
+
+# 3. 发送用户通知
+curl -X POST "http://localhost:8080/rabbitmq/test/send/user-notice?message=测试通知"
+
+# 4. 测试返回机制
+curl -X POST "http://localhost:8080/rabbitmq/test/send/test-return?message=测试返回"
+
+# 5. 发送字符串消息
+curl -X POST "http://localhost:8080/rabbitmq/test/send/string?message=Hello"
+```
+
+## 日志查看
+
+测试时重点关注以下日志:
+
+1. **启动日志**:
+   ```
+   RabbitMQ 连接工厂配置完成 - Host: 120.26.186.130, Port: 5672...
+   RabbitTemplate 配置完成
+   ```
+
+2. **发送成功日志**:
+   ```
+   消息发送成功到交换机,correlationData: ...
+   ```
+
+3. **接收消息日志**:
+   ```
+   ========== 收到订单队列消息 ==========
+   消息内容: ...
+   =====================================
+   ```
+
+4. **消息退回日志**:
+   ```
+   消息被退回 - Exchange: ..., RoutingKey: ..., ReplyCode: ...
+   ```
+
+## 下一步
+
+测试通过后,可以:
+1. 根据实际业务需求修改消息格式
+2. 在监听器中添加业务处理逻辑
+3. 配置消息重试机制
+4. 添加消息持久化配置
+5. 配置死信队列(如果需要)

+ 2 - 1
alien-config/src/main/java/shop/alien/config/RabbitMq/RabbitMQConfig.java

@@ -1,7 +1,7 @@
 
 package shop.alien.config.RabbitMq;
-
 import org.springframework.amqp.core.*;
+import org.springframework.amqp.rabbit.annotation.EnableRabbit;
 import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
 import org.springframework.amqp.rabbit.connection.ConnectionFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
 
 @Configuration
 @EnableRetry
+@EnableRabbit  // 启用 RabbitMQ 监听器功能
 public class RabbitMQConfig {
 
     private static final Logger logger = LoggerFactory.getLogger(RabbitMQConfig.class);

+ 62 - 0
alien-config/src/main/java/shop/alien/config/RabbitMq/RabbitMQMessageListener.java

@@ -0,0 +1,62 @@
+package shop.alien.config.RabbitMq;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.support.AmqpHeaders;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.messaging.handler.annotation.Payload;
+import org.springframework.stereotype.Component;
+
+/**
+ * RabbitMQ 消息监听器 - 用于测试消息接收
+ * 
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Component
+public class RabbitMQMessageListener {
+
+    /**
+     * 监听订单队列消息
+     */
+    @RabbitListener(queues = "order.queue")
+    public void handleOrderMessage(@Payload String message, 
+                                   Message amqpMessage,
+                                   @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
+        log.info("========== 收到订单队列消息 ==========");
+        log.info("消息内容: {}", message);
+        log.info("Delivery Tag: {}", deliveryTag);
+        log.info("消息属性 - Exchange: {}, RoutingKey: {}", 
+                amqpMessage.getMessageProperties().getReceivedExchange(),
+                amqpMessage.getMessageProperties().getReceivedRoutingKey());
+        log.info("消息ID: {}", amqpMessage.getMessageProperties().getMessageId());
+        log.info("时间戳: {}", amqpMessage.getMessageProperties().getTimestamp());
+        log.info("=====================================");
+        
+        // 这里可以添加业务处理逻辑
+        // 注意:如果 acknowledge-mode 是 manual,需要手动确认
+        // channel.basicAck(deliveryTag, false);
+    }
+
+    /**
+     * 监听用户通知队列消息
+     */
+    @RabbitListener(queues = "user.notice.queue")
+    public void handleUserNoticeMessage(@Payload String message,
+                                        Message amqpMessage,
+                                        @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
+        log.info("========== 收到用户通知队列消息 ==========");
+        log.info("消息内容: {}", message);
+        log.info("Delivery Tag: {}", deliveryTag);
+        log.info("消息属性 - Exchange: {}, RoutingKey: {}", 
+                amqpMessage.getMessageProperties().getReceivedExchange(),
+                amqpMessage.getMessageProperties().getReceivedRoutingKey());
+        log.info("消息ID: {}", amqpMessage.getMessageProperties().getMessageId());
+        log.info("=========================================");
+        
+        // 这里可以添加业务处理逻辑
+    }
+
+}

+ 170 - 0
alien-config/src/main/java/shop/alien/config/RabbitMq/RabbitMQTestController.java

@@ -0,0 +1,170 @@
+package shop.alien.config.RabbitMq;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.core.MessageProperties;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * RabbitMQ 测试 Controller
+ * 用于测试 RabbitMQ 消息发送功能
+ * 
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@RestController
+@RequestMapping("/rabbitmq/test")
+@RequiredArgsConstructor
+public class RabbitMQTestController {
+
+    private final RabbitTemplate rabbitTemplate;
+    private final MessageConverter messageConverter;
+
+    /**
+     * 测试发送订单消息
+     */
+    @PostMapping("/send/order")
+    public Map<String, Object> sendOrderMessage(@RequestParam(required = false, defaultValue = "测试订单消息") String message) {
+        Map<String, Object> result = new HashMap<>();
+        
+        try {
+            // 构建消息内容
+            Map<String, Object> orderData = new HashMap<>();
+            orderData.put("orderId", "ORDER-" + System.currentTimeMillis());
+            orderData.put("message", message);
+            orderData.put("timestamp", LocalDateTime.now().toString());
+            
+            // 发送消息到订单交换机
+            rabbitTemplate.convertAndSend("order.exchange", "order.routing.key", orderData);
+            
+            result.put("success", true);
+            result.put("message", "订单消息发送成功");
+            result.put("data", orderData);
+            log.info("订单消息发送成功: {}", orderData);
+            
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", "订单消息发送失败: " + e.getMessage());
+            log.error("订单消息发送失败", e);
+        }
+        
+        return result;
+    }
+
+    /**
+     * 测试发送用户通知消息
+     */
+    @PostMapping("/send/user-notice")
+    public Map<String, Object> sendUserNoticeMessage(@RequestParam(required = false, defaultValue = "测试用户通知") String message) {
+        Map<String, Object> result = new HashMap<>();
+        
+        try {
+            // 构建消息内容
+            Map<String, Object> noticeData = new HashMap<>();
+            noticeData.put("userId", "USER-" + System.currentTimeMillis());
+            noticeData.put("message", message);
+            noticeData.put("timestamp", LocalDateTime.now().toString());
+            noticeData.put("type", "NOTICE");
+            
+            // 发送消息到用户通知交换机(使用主题路由)
+            rabbitTemplate.convertAndSend("user.notice.exchange", "user.notice.test", noticeData);
+            
+            result.put("success", true);
+            result.put("message", "用户通知消息发送成功");
+            result.put("data", noticeData);
+            log.info("用户通知消息发送成功: {}", noticeData);
+            
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", "用户通知消息发送失败: " + e.getMessage());
+            log.error("用户通知消息发送失败", e);
+        }
+        
+        return result;
+    }
+
+    /**
+     * 测试发送字符串消息
+     */
+    @PostMapping("/send/string")
+    public Map<String, Object> sendStringMessage(@RequestParam String message,
+                                                  @RequestParam(required = false, defaultValue = "order.queue") String queue) {
+        Map<String, Object> result = new HashMap<>();
+        
+        try {
+            // 直接发送字符串消息
+            rabbitTemplate.convertAndSend("order.exchange", "order.routing.key", message);
+            
+            result.put("success", true);
+            result.put("message", "字符串消息发送成功");
+            result.put("data", message);
+            log.info("字符串消息发送成功: {}", message);
+            
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", "字符串消息发送失败: " + e.getMessage());
+            log.error("字符串消息发送失败", e);
+        }
+        
+        return result;
+    }
+
+    /**
+     * 测试消息确认机制 - 发送一个会失败的消息(路由到不存在的队列)
+     */
+    @PostMapping("/send/test-return")
+    public Map<String, Object> sendTestReturnMessage(@RequestParam(required = false, defaultValue = "测试返回消息") String message) {
+        Map<String, Object> result = new HashMap<>();
+        
+        try {
+            // 发送到一个不存在的路由键,触发返回回调
+            rabbitTemplate.convertAndSend("order.exchange", "non.existent.routing.key", message);
+            
+            result.put("success", true);
+            result.put("message", "测试返回消息已发送(应该会被退回)");
+            result.put("data", message);
+            log.info("测试返回消息发送成功(应该会被退回): {}", message);
+            
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", "测试返回消息发送失败: " + e.getMessage());
+            log.error("测试返回消息发送失败", e);
+        }
+        
+        return result;
+    }
+
+    /**
+     * 测试连接状态
+     */
+    @GetMapping("/connection/status")
+    public Map<String, Object> checkConnectionStatus() {
+        Map<String, Object> result = new HashMap<>();
+        
+        try {
+            // 尝试发送一个测试消息来验证连接
+            String testMessage = "连接测试消息 - " + System.currentTimeMillis();
+            rabbitTemplate.convertAndSend("order.exchange", "order.routing.key", testMessage);
+            
+            result.put("success", true);
+            result.put("message", "RabbitMQ 连接正常");
+            result.put("timestamp", LocalDateTime.now().toString());
+            log.info("RabbitMQ 连接状态检查成功");
+            
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", "RabbitMQ 连接失败: " + e.getMessage());
+            log.error("RabbitMQ 连接状态检查失败", e);
+        }
+        
+        return result;
+    }
+}