> listeners,
RedisMQTemplate redisTemplate,
@Value("${spring.application.name}") String groupName,
RedissonClient redissonClient) {
@@ -92,14 +88,13 @@ public class YudaoMQAutoConfiguration {
/**
* 创建 Redis Stream 集群消费的容器
- *
- * Redis Stream 的 xreadgroup 命令:https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html
+ *
+ * 基础知识:Redis Stream 的 xreadgroup 命令
*/
@Bean(initMethod = "start", destroyMethod = "stop")
- @ConditionalOnBean(AbstractStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听
- @ConditionalOnProperty(prefix = "yudao.mq.redis.stream", value = "enable", matchIfMissing = true) // 允许使用 yudao.mq.redis.stream.enable=false 禁用多租户
+ @ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听
public StreamMessageListenerContainer> redisStreamMessageListenerContainer(
- RedisMQTemplate redisMQTemplate, List> listeners) {
+ RedisMQTemplate redisMQTemplate, List> listeners) {
RedisTemplate redisTemplate = redisMQTemplate.getRedisTemplate();
checkRedisVersion(redisTemplate);
// 第一步,创建 StreamMessageListenerContainer 容器
@@ -111,8 +106,7 @@ public class YudaoMQAutoConfiguration {
.build();
// 创建 container 对象
StreamMessageListenerContainer> container =
-// StreamMessageListenerContainer.create(redisTemplate.getRequiredConnectionFactory(), containerOptions);
- DefaultStreamMessageListenerContainerX.create(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory(), containerOptions);
+ StreamMessageListenerContainer.create(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory(), containerOptions);
// 第二步,注册监听器,消费对应的 Stream 主题
String consumerName = buildConsumerName();
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/RedisMQTemplate.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/RedisMQTemplate.java
similarity index 80%
rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/RedisMQTemplate.java
rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/RedisMQTemplate.java
index 8a31feda7..5755ffa51 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/RedisMQTemplate.java
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/RedisMQTemplate.java
@@ -1,10 +1,10 @@
-package cn.iocoder.yudao.framework.mq.core;
+package cn.iocoder.yudao.framework.mq.redis.core;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor;
-import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage;
-import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
+import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor;
+import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage;
+import cn.iocoder.yudao.framework.mq.redis.core.pubsub.AbstractRedisChannelMessage;
+import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.data.redis.connection.stream.RecordId;
@@ -35,7 +35,7 @@ public class RedisMQTemplate {
*
* @param message 消息
*/
- public void send(T message) {
+ public void send(T message) {
try {
sendMessageBefore(message);
// 发送消息
@@ -51,7 +51,7 @@ public class RedisMQTemplate {
* @param message 消息
* @return 消息记录的编号对象
*/
- public RecordId send(T message) {
+ public RecordId send(T message) {
try {
sendMessageBefore(message);
// 发送消息
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/interceptor/RedisMessageInterceptor.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/interceptor/RedisMessageInterceptor.java
similarity index 79%
rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/interceptor/RedisMessageInterceptor.java
rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/interceptor/RedisMessageInterceptor.java
index 11d8e1337..dbcee7fe2 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/interceptor/RedisMessageInterceptor.java
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/interceptor/RedisMessageInterceptor.java
@@ -1,6 +1,6 @@
-package cn.iocoder.yudao.framework.mq.core.interceptor;
+package cn.iocoder.yudao.framework.mq.redis.core.interceptor;
-import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage;
+import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage;
/**
* {@link AbstractRedisMessage} 消息拦截器
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/job/RedisPendingMessageResendJob.java
similarity index 93%
rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java
rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/job/RedisPendingMessageResendJob.java
index ea0f53d19..b84f17c15 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/job/RedisPendingMessageResendJob.java
@@ -1,8 +1,8 @@
-package cn.iocoder.yudao.framework.mq.job;
+package cn.iocoder.yudao.framework.mq.redis.core.job;
import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
+import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
+import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
@@ -33,7 +33,7 @@ public class RedisPendingMessageResendJob {
*/
private static final int EXPIRE_TIME = 5 * 60;
- private final List> listeners;
+ private final List> listeners;
private final RedisMQTemplate redisTemplate;
private final String groupName;
private final RedissonClient redissonClient;
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/message/AbstractRedisMessage.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/message/AbstractRedisMessage.java
similarity index 88%
rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/message/AbstractRedisMessage.java
rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/message/AbstractRedisMessage.java
index f02e89d6f..ee40814dd 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/message/AbstractRedisMessage.java
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/message/AbstractRedisMessage.java
@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.mq.core.message;
+package cn.iocoder.yudao.framework.mq.redis.core.message;
import lombok.Data;
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessage.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessage.java
new file mode 100644
index 000000000..d5ea5b9d5
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessage.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.framework.mq.redis.core.pubsub;
+
+import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Redis Channel Message 抽象类
+ *
+ * @author 芋道源码
+ */
+public abstract class AbstractRedisChannelMessage extends AbstractRedisMessage {
+
+ /**
+ * 获得 Redis Channel,默认使用类名
+ *
+ * @return Channel
+ */
+ @JsonIgnore // 避免序列化。原因是,Redis 发布 Channel 消息的时候,已经会指定。
+ public String getChannel() {
+ return getClass().getSimpleName();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/pubsub/AbstractChannelMessageListener.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessageListener.java
similarity index 85%
rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/pubsub/AbstractChannelMessageListener.java
rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessageListener.java
index e7d737d1b..fd7c910c9 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/pubsub/AbstractChannelMessageListener.java
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessageListener.java
@@ -1,10 +1,10 @@
-package cn.iocoder.yudao.framework.mq.core.pubsub;
+package cn.iocoder.yudao.framework.mq.redis.core.pubsub;
import cn.hutool.core.util.TypeUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
-import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor;
-import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage;
+import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
+import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor;
+import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.data.redis.connection.Message;
@@ -20,7 +20,7 @@ import java.util.List;
*
* @author 芋道源码
*/
-public abstract class AbstractChannelMessageListener implements MessageListener {
+public abstract class AbstractRedisChannelMessageListener implements MessageListener {
/**
* 消息类型
@@ -37,7 +37,7 @@ public abstract class AbstractChannelMessageListener
+public abstract class AbstractRedisStreamMessageListener
implements StreamListener> {
/**
@@ -48,7 +48,7 @@ public abstract class AbstractStreamMessageListener> extends DefaultStreamMessageListenerContainer {
-
- /**
- * 参考 {@link StreamMessageListenerContainer#create(RedisConnectionFactory, StreamMessageListenerContainerOptions)} 的实现
- */
- public static > StreamMessageListenerContainer create(RedisConnectionFactory connectionFactory, StreamMessageListenerContainer.StreamMessageListenerContainerOptions options) {
- Assert.notNull(connectionFactory, "RedisConnectionFactory must not be null!");
- Assert.notNull(options, "StreamMessageListenerContainerOptions must not be null!");
- return new DefaultStreamMessageListenerContainerX<>(connectionFactory, options);
- }
-
- public DefaultStreamMessageListenerContainerX(RedisConnectionFactory connectionFactory, StreamMessageListenerContainerOptions containerOptions) {
- super(connectionFactory, containerOptions);
- }
-
- /**
- * 参考 {@link DefaultStreamMessageListenerContainer#register(StreamReadRequest, StreamListener)} 的实现
- */
- @Override
- public Subscription register(StreamReadRequest streamRequest, StreamListener listener) {
- return this.doRegisterX(getReadTaskX(streamRequest, listener));
- }
-
- @SuppressWarnings("unchecked")
- private StreamPollTask getReadTaskX(StreamReadRequest streamRequest, StreamListener listener) {
- StreamPollTask task = ReflectUtil.invoke(this, "getReadTask", streamRequest, listener);
- // 修改 readFunction 方法
- Function> readFunction = (Function>) ReflectUtil.getFieldValue(task, "readFunction");
- ReflectUtil.setFieldValue(task, "readFunction", (Function>) readOffset -> {
- List records = readFunction.apply(readOffset);
- //【重点】保证 records 不是空,避免 NPE 的问题!!!
- return records != null ? records : Collections.emptyList();
- });
- return task;
- }
-
- private Subscription doRegisterX(Task task) {
- return ReflectUtil.invoke(this, "doRegister", task);
- }
-
-}
-
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index c47aa4d7b..660865453 100644
--- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1,2 @@
-cn.iocoder.yudao.framework.mq.config.YudaoMQAutoConfiguration
\ No newline at end of file
+cn.iocoder.yudao.framework.mq.redis.config.YudaoRedisMQAutoConfiguration
+cn.iocoder.yudao.framework.mq.rabbitmq.config.YudaoRabbitMQAutoConfiguration
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md
new file mode 100644
index 000000000..08586b379
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md
@@ -0,0 +1 @@
+
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md
new file mode 100644
index 000000000..b66d6334c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md
@@ -0,0 +1 @@
+
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md
new file mode 100644
index 000000000..eff46e2f7
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md
@@ -0,0 +1 @@
+
diff --git a/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md
new file mode 100644
index 000000000..08586b379
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md
@@ -0,0 +1 @@
+
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/CouponTakeByRegisterConsumer.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/CouponTakeByRegisterConsumer.java
new file mode 100644
index 000000000..4d7a092c4
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/CouponTakeByRegisterConsumer.java
@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.promotion.mq.consumer.coupon;
+
+import cn.iocoder.yudao.module.member.message.user.MemberUserCreateMessage;
+import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户注册时,发送优惠劵的消费者,基 {@link MemberUserCreateMessage} 消息
+ *
+ * @author owen
+ */
+@Component
+@Slf4j
+public class CouponTakeByRegisterConsumer {
+
+ @Resource
+ private CouponService couponService;
+
+ @EventListener
+ @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
+ public void onMessage(MemberUserCreateMessage message) {
+ log.info("[onMessage][消息内容({})]", message);
+ couponService.takeCouponByRegister(message.getUserId());
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java
deleted file mode 100644
index 5876a4daf..000000000
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.promotion.mq.consumer.coupon;
-
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
-import cn.iocoder.yudao.module.promotion.mq.message.coupon.UserCreateMessage;
-import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-
-/**
- * 针对 {@link UserCreateMessage} 的消费者
- *
- * @author owen
- */
-@Component
-@Slf4j
-public class UserCreateConsumer extends AbstractStreamMessageListener {
-
- @Resource
- private CouponService couponService;
-
- @Override
- public void onMessage(UserCreateMessage message) {
- log.info("[onMessage][消息内容({})]", message);
- couponService.takeCouponByRegister(message.getUserId());
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/package-info.java
new file mode 100644
index 000000000..95c23df74
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的消费者
+ */
+package cn.iocoder.yudao.module.promotion.mq.consumer;
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java
deleted file mode 100644
index 370bdf71a..000000000
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.promotion.mq.message.coupon;
-
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import javax.validation.constraints.NotNull;
-
-/**
- * 会员用户创建消息
- *
- * @author owen
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class UserCreateMessage extends AbstractStreamMessage {
-
- /**
- * 用户编号
- */
- @NotNull(message = "用户编号不能为空")
- private Long userId;
-
- @Override
- public String getStreamKey() {
- return "member.user.create";
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/package-info.java
new file mode 100644
index 000000000..912504e76
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的消息
+ */
+package cn.iocoder.yudao.module.promotion.mq.message;
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/producer/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/producer/package-info.java
new file mode 100644
index 000000000..e7b8d1b4c
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/producer/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的生产者
+ */
+package cn.iocoder.yudao.module.promotion.mq.producer;
diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/package-info.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/package-info.java
new file mode 100644
index 000000000..6ae3b6448
--- /dev/null
+++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的消息
+ */
+package cn.iocoder.yudao.module.member.message;
diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/user/MemberUserCreateMessage.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/user/MemberUserCreateMessage.java
new file mode 100644
index 000000000..cfb24eb72
--- /dev/null
+++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/user/MemberUserCreateMessage.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.member.message.user;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 会员用户创建消息
+ *
+ * @author owen
+ */
+@Data
+public class MemberUserCreateMessage {
+
+ /**
+ * 用户编号
+ */
+ @NotNull(message = "用户编号不能为空")
+ private Long userId;
+
+}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
index 998c70c21..5b68d6984 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
@@ -4,7 +4,7 @@ Content-Type: application/json
tenant-id: {{appTenentId}}
{
- "mobile": "15601691300",
+ "mobile": "15601691388",
"password": "admin123"
}
@@ -14,7 +14,7 @@ Content-Type: application/json
tenant-id: {{appTenentId}}
{
- "mobile": "15601691399",
+ "mobile": "15601691388",
"scene": 1
}
@@ -22,9 +22,10 @@ tenant-id: {{appTenentId}}
POST {{appApi}}/member/auth/sms-login
Content-Type: application/json
tenant-id: {{appTenentId}}
+terminal: 30
{
- "mobile": "15601691301",
+ "mobile": "15601691388",
"code": 9999
}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/consumer/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/consumer/package-info.java
new file mode 100644
index 000000000..521f60b8c
--- /dev/null
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/consumer/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的消费者
+ */
+package cn.iocoder.yudao.module.member.mq.consumer;
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/package-info.java
new file mode 100644
index 000000000..6489394a1
--- /dev/null
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的消息
+ */
+package cn.iocoder.yudao.module.member.mq.message;
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/MemberUserCreateMessage.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/MemberUserCreateMessage.java
deleted file mode 100644
index cd411cc74..000000000
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/MemberUserCreateMessage.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.member.mq.message.user;
-
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import javax.validation.constraints.NotNull;
-
-/**
- * 会员用户创建消息
- *
- * @author owen
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class MemberUserCreateMessage extends AbstractStreamMessage {
-
- /**
- * 用户编号
- */
- @NotNull(message = "用户编号不能为空")
- private Long userId;
-
- @Override
- public String getStreamKey() {
- return "member.user.create";
- }
-
-}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/package-info.java
new file mode 100644
index 000000000..dff4c99a9
--- /dev/null
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 消息队列的生产者
+ */
+package cn.iocoder.yudao.module.member.mq.producer;
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/MemberUserProducer.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/MemberUserProducer.java
index 4a88f419f..8687bb071 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/MemberUserProducer.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/MemberUserProducer.java
@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.member.mq.producer.user;
-import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
-import cn.iocoder.yudao.module.member.mq.message.user.MemberUserCreateMessage;
+import cn.iocoder.yudao.module.member.message.user.MemberUserCreateMessage;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -17,7 +17,7 @@ import javax.annotation.Resource;
public class MemberUserProducer {
@Resource
- private RedisMQTemplate redisMQTemplate;
+ private ApplicationContext applicationContext;
/**
* 发送 {@link MemberUserCreateMessage} 消息
@@ -25,7 +25,7 @@ public class MemberUserProducer {
* @param userId 用户编号
*/
public void sendUserCreateMessage(Long userId) {
- redisMQTemplate.send(new MemberUserCreateMessage().setUserId(userId));
+ applicationContext.publishEvent(new MemberUserCreateMessage().setUserId(userId));
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http
index e8213e5cd..ee24e928b 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http
@@ -6,9 +6,9 @@ tenant-id: {{adminTenentId}}
{
"templateCode": "test_01",
- "mobile": "156016913900",
- "params": {
- "key01": "value01",
- "key02": "value02"
+ "mobile": "15601691390",
+ "templateParams": {
+ "operation": "value01",
+ "code": "value02"
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/mail/MailSendConsumer.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/mail/MailSendConsumer.java
index 3cff145b8..7e7b487fb 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/mail/MailSendConsumer.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/mail/MailSendConsumer.java
@@ -1,10 +1,10 @@
package cn.iocoder.yudao.module.system.mq.consumer.mail;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
-import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage;
import cn.iocoder.yudao.module.system.service.mail.MailSendService;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -16,12 +16,13 @@ import javax.annotation.Resource;
*/
@Component
@Slf4j
-public class MailSendConsumer extends AbstractStreamMessageListener {
+public class MailSendConsumer {
@Resource
private MailSendService mailSendService;
- @Override
+ @EventListener
+ @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
public void onMessage(MailSendMessage message) {
log.info("[onMessage][消息内容({})]", message);
mailSendService.doSendMail(message);
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
index 3b4ff216b..39753b66e 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
@@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.system.mq.consumer.sms;
import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage;
import cn.iocoder.yudao.module.system.service.sms.SmsSendService;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -15,12 +16,13 @@ import javax.annotation.Resource;
*/
@Component
@Slf4j
-public class SmsSendConsumer extends AbstractStreamMessageListener {
+public class SmsSendConsumer {
@Resource
private SmsSendService smsSendService;
- @Override
+ @EventListener
+ @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
public void onMessage(SmsSendMessage message) {
log.info("[onMessage][消息内容({})]", message);
smsSendService.doSendSms(message);
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java
index 0adafa409..943d69b09 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java
@@ -1,8 +1,6 @@
package cn.iocoder.yudao.module.system.mq.message.mail;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
import lombok.Data;
-import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@@ -13,8 +11,7 @@ import javax.validation.constraints.NotNull;
* @author 芋道源码
*/
@Data
-@EqualsAndHashCode(callSuper = true)
-public class MailSendMessage extends AbstractStreamMessage {
+public class MailSendMessage {
/**
* 邮件日志编号
@@ -47,9 +44,4 @@ public class MailSendMessage extends AbstractStreamMessage {
@NotEmpty(message = "邮件内容不能为空")
private String content;
- @Override
- public String getStreamKey() {
- return "system.mail.send";
- }
-
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessage.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessage.java
index 42a32623a..e4baefcec 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessage.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessage.java
@@ -1,9 +1,7 @@
package cn.iocoder.yudao.module.system.mq.message.sms;
import cn.iocoder.yudao.framework.common.core.KeyValue;
-import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
import lombok.Data;
-import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.util.List;
@@ -14,8 +12,7 @@ import java.util.List;
* @author 芋道源码
*/
@Data
-@EqualsAndHashCode(callSuper = true)
-public class SmsSendMessage extends AbstractStreamMessage {
+public class SmsSendMessage {
/**
* 短信日志编号
@@ -42,9 +39,4 @@ public class SmsSendMessage extends AbstractStreamMessage {
*/
private List> templateParams;
- @Override
- public String getStreamKey() {
- return "system.sms.send";
- }
-
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
index 51016e240..5894332cb 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.system.mq.producer.mail;
-import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -18,7 +18,7 @@ import javax.annotation.Resource;
public class MailProducer {
@Resource
- private RedisMQTemplate redisMQTemplate;
+ private ApplicationContext applicationContext;
/**
* 发送 {@link MailSendMessage} 消息
@@ -35,7 +35,7 @@ public class MailProducer {
MailSendMessage message = new MailSendMessage()
.setLogId(sendLogId).setMail(mail).setAccountId(accountId)
.setNickname(nickname).setTitle(title).setContent(content);
- redisMQTemplate.send(message);
+ applicationContext.publishEvent(message);
}
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
index 32bbde369..379f2e229 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
@@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.system.mq.producer.sms;
import cn.iocoder.yudao.framework.common.core.KeyValue;
-import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -20,7 +20,7 @@ import java.util.List;
public class SmsProducer {
@Resource
- private RedisMQTemplate redisMQTemplate;
+ private ApplicationContext applicationContext;
/**
* 发送 {@link SmsSendMessage} 消息
@@ -35,7 +35,7 @@ public class SmsProducer {
Long channelId, String apiTemplateId, List> templateParams) {
SmsSendMessage message = new SmsSendMessage().setLogId(logId).setMobile(mobile);
message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams);
- redisMQTemplate.send(message);
+ applicationContext.publishEvent(message);
}
}
diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml
index 2e9db5599..13c6f92ab 100644
--- a/yudao-server/src/main/resources/application-dev.yaml
+++ b/yudao-server/src/main/resources/application-dev.yaml
@@ -94,6 +94,23 @@ spring:
jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
+--- #################### 消息队列相关 ####################
+
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+ name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+ # RabbitMQ 配置项,对应 RabbitProperties 配置类
+ rabbitmq:
+ host: 127.0.0.1 # RabbitMQ 服务的地址
+ port: 5672 # RabbitMQ 服务的端口
+ username: guest # RabbitMQ 服务的账号
+ password: guest # RabbitMQ 服务的密码
+ # Kafka 配置项,对应 KafkaProperties 配置类
+ kafka:
+ bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml
index e98110a40..4424329a3 100644
--- a/yudao-server/src/main/resources/application-local.yaml
+++ b/yudao-server/src/main/resources/application-local.yaml
@@ -109,6 +109,23 @@ spring:
jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
+--- #################### 消息队列相关 ####################
+
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+ name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+ # RabbitMQ 配置项,对应 RabbitProperties 配置类
+ rabbitmq:
+ host: 127.0.0.1 # RabbitMQ 服务的地址
+ port: 5672 # RabbitMQ 服务的端口
+ username: guest # RabbitMQ 服务的账号
+ password: guest # RabbitMQ 服务的密码
+ # Kafka 配置项,对应 KafkaProperties 配置类
+ kafka:
+ bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml
index 1e507c8ac..9125bd49f 100644
--- a/yudao-server/src/main/resources/application.yaml
+++ b/yudao-server/src/main/resources/application.yaml
@@ -106,6 +106,32 @@ aj:
req-check-minute-limit: 60 # check 接口一分钟内请求数限制
req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制
+--- #################### 消息队列相关 ####################
+
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+ # Producer 配置项
+ producer:
+ group: ${spring.application.name}_PRODUCER # 生产者分组
+
+spring:
+ # Kafka 配置项,对应 KafkaProperties 配置类
+ kafka:
+ # Kafka Producer 配置项
+ producer:
+ acks: 1 # 0-不应答。1-leader 应答。all-所有 leader 和 follower 应答。
+ retries: 3 # 发送失败时,重试发送的次数
+ value-serializer: org.springframework.kafka.support.serializer.JsonSerializer # 消息的 value 的序列化
+ # Kafka Consumer 配置项
+ consumer:
+ auto-offset-reset: earliest # 设置消费者分组最初的消费进度为 earliest 。可参考博客 https://blog.csdn.net/lishuangzhe7047/article/details/74530417 理解
+ value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
+ properties:
+ spring.json.trusted.packages: '*'
+ # Kafka Consumer Listener 监听器配置
+ listener:
+ missing-topics-fatal: false # 消费监听接口监听的主题不存在时,默认会报错。所以通过设置为 false ,解决报错
+
--- #################### 芋道相关配置 ####################
yudao:
@@ -145,12 +171,6 @@ yudao:
- cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants
- cn.iocoder.yudao.module.system.enums.ErrorCodeConstants
- cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants
- mq:
- redis:
- pubsub:
- enable: false # 是否开启 Redis pubsub 广播消费,默认为 true。这里设置成 false,可以按需开启
- stream:
- enable: false # 是否开启 Redis stream 集群消费,默认为 true。这里设置成 false,可以按需开启
tenant: # 多租户相关配置项
enable: true
ignore-urls: