|
@@ -10,7 +10,6 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import com.chelvc.framework.base.context.ApplicationContextHolder;
|
|
|
-import com.chelvc.framework.common.function.Executor;
|
|
|
import com.chelvc.framework.common.util.AssertUtils;
|
|
|
import com.chelvc.framework.common.util.StringUtils;
|
|
|
import com.chelvc.framework.redis.annotation.RedisMQConsumer;
|
|
@@ -18,7 +17,6 @@ import com.chelvc.framework.redis.context.RedisStreamHolder;
|
|
|
import lombok.NonNull;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.core.env.Environment;
|
|
|
-import org.springframework.data.redis.RedisSystemException;
|
|
|
import org.springframework.data.redis.connection.stream.Consumer;
|
|
|
import org.springframework.data.redis.connection.stream.MapRecord;
|
|
|
import org.springframework.data.redis.connection.stream.ReadOffset;
|
|
@@ -36,16 +34,13 @@ import org.springframework.data.redis.stream.StreamMessageListenerContainer;
|
|
|
@Slf4j
|
|
|
public class DefaultRedisMQListenerContainer<T> implements RedisMQListenerContainer<T> {
|
|
|
private final String name = StringUtils.uuid();
|
|
|
+ private int idle;
|
|
|
private String topic;
|
|
|
private String group;
|
|
|
- private int idle;
|
|
|
- private int batch;
|
|
|
private Consumer consumer;
|
|
|
private ExecutorService executor;
|
|
|
- private StreamOffset<String> offset;
|
|
|
private ScheduledExecutorService cleaner;
|
|
|
private MessageStreamListener<T> listener;
|
|
|
- private Executor starter;
|
|
|
private StreamMessageListenerContainer<String, MapRecord<String, String, String>> container;
|
|
|
|
|
|
/**
|
|
@@ -93,49 +88,25 @@ public class DefaultRedisMQListenerContainer<T> implements RedisMQListenerContai
|
|
|
@NonNull RedisMQListener<T> listener, @NonNull ExecutorService executor) {
|
|
|
AssertUtils.nonempty(topic, () -> "Consumer topic must not be empty");
|
|
|
AssertUtils.nonempty(group, () -> "Consumer group must not be empty");
|
|
|
- AssertUtils.check((this.batch = batch) > 0, () -> "Consumer batch must be greater than 0");
|
|
|
+ AssertUtils.check(batch > 0, () -> "Consumer batch must be greater than 0");
|
|
|
AssertUtils.check((this.idle = RedisStreamHolder.getIdle()) > 0, () -> "Consumer idle must be greater than 0");
|
|
|
Environment environment = ApplicationContextHolder.getEnvironment();
|
|
|
this.topic = RedisStreamHolder.isolate(environment.resolvePlaceholders(topic));
|
|
|
this.group = RedisStreamHolder.isolate(environment.resolvePlaceholders(group));
|
|
|
this.consumer = Consumer.from(this.group, this.name);
|
|
|
- this.offset = StreamOffset.create(this.topic, ReadOffset.lastConsumed());
|
|
|
this.listener = new MessageStreamListener<>(
|
|
|
type, this.topic, this.consumer, listener, this.executor = executor
|
|
|
);
|
|
|
|
|
|
- // 初始化消费者容器启动函数,当检测到消费者组不存在则自动重新创建消费者并重启消费者容器
|
|
|
- this.starter = () -> {
|
|
|
- // 停止当前容器(如果存在)
|
|
|
- if (this.container != null) {
|
|
|
- try {
|
|
|
- this.container.stop();
|
|
|
- } catch (Throwable t) {
|
|
|
- log.warn("RedisMQ consumer container stop failed: {}, {}", this.consumer, t.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 初始化消费者组
|
|
|
- RedisStreamHolder.initializeConsumerGroup(this.topic, this.group);
|
|
|
+ // 初始化消费者组
|
|
|
+ RedisStreamHolder.initializeConsumerGroup(this.topic, this.group);
|
|
|
|
|
|
- // 初始化消息监听器容器
|
|
|
- this.container = RedisStreamHolder.initializeMessageListenerContainer(
|
|
|
- this.listener, this.consumer, this.offset, this.batch, this.executor,
|
|
|
- t -> {
|
|
|
- if (!(t instanceof RedisSystemException) || StringUtils.isEmpty(t.getMessage())
|
|
|
- || !t.getMessage().contains("NOGROUP")) {
|
|
|
- log.error("RedisMQ consumer handle exception: {}", this.consumer, t);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 如果是消费者组不存在异常则重启容器
|
|
|
- log.warn("RedisMQ consumer group has been destroyed and the container will be restarted");
|
|
|
- this.starter.execute();
|
|
|
- }
|
|
|
- );
|
|
|
- this.container.start();
|
|
|
- };
|
|
|
- this.starter.execute();
|
|
|
+ // 初始化消息监听器容器
|
|
|
+ StreamOffset<String> offset = StreamOffset.create(this.topic, ReadOffset.lastConsumed());
|
|
|
+ this.container = RedisStreamHolder.initializeMessageListenerContainer(
|
|
|
+ this.listener, this.consumer, offset, batch, this.executor
|
|
|
+ );
|
|
|
+ this.container.start();
|
|
|
|
|
|
// 初始化消费者清理定时器
|
|
|
this.cleaner = Executors.newScheduledThreadPool(1);
|