我使用 redis(version 6.x
) 流发送一些消息,我的生产者是 Python 3,消费者是 Java Redis 客户端。现在我成功地将消息发送到 redis 流,但我不知道客户端正在连接 redis(从日志我可以知道一些消息消耗了但似乎新消息没有消耗),因为消耗的消息没有在 Redis 流中删除即使通过客户确认的消息。
这是我的java客户端代码:
@Component
@Slf4j
public class StreamMessageListener implements StreamListener<String, MapRecord<String, String, String>> {
@Value("${dolphin.redis.stream.group}")
private String groupName;
@Value("${dolphin.redis.user.sub.list}")
private String userSub;
private final StringRedisTemplate stringRedisTemplate;
private final RedisTemplate<String, Object> articleRedisTemplate;
private final RedisTemplate<String, Long> redisLongTemplate;
private final ISubRelationService subRelationService;
private final IArticleService articleService;
public StreamMessageListener(StringRedisTemplate stringRedisTemplate,
@Qualifier("redisObjectTemplate") RedisTemplate<String, Object> articleRedisTemplate,
ISubRelationService subRelationService,
@Qualifier("redisLongTemplate") RedisTemplate<String, Long> redisLongTemplate,
IArticleService articleService) {
this.stringRedisTemplate = stringRedisTemplate;
this.articleRedisTemplate = articleRedisTemplate;
this.subRelationService = subRelationService;
this.redisLongTemplate = redisLongTemplate;
this.articleService = articleService;
}
@Override
public void onMessage(MapRecord<String, String, String> message) {
RecordId messageId = message.getId();
Map<String, String> body = message.getValue();
log.info("stream message。messageId={}, stream={}, body={}", messageId, message.getStream(), body);
}
}
这是消费者代码:
@Component
@Slf4j
public class StreamConsumerRunner implements ApplicationRunner, DisposableBean {
@Value("${dolphin.redis.stream.consumer}")
private String consumer;
@Value("${dolphin.redis.stream.group}")
private String groupName;
private final RedisConnectionFactory redisConnectionFactory;
private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
private final StreamMessageListener streamMessageListener;
private final StringRedisTemplate stringRedisTemplate;
private StreamMessageListenerContainer<String, MapRecord<String, String, String>> streamMessageListenerContainer;
public StreamConsumerRunner(RedisConnectionFactory redisConnectionFactory,
ThreadPoolTaskExecutor threadPoolTaskExecutor,
StreamMessageListener streamMessageListener,
StringRedisTemplate stringRedisTemplate) {
this.redisConnectionFactory = redisConnectionFactory;
this.threadPoolTaskExecutor = threadPoolTaskExecutor;
this.streamMessageListener = streamMessageListener;
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public void run(ApplicationArguments args) {
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, MapRecord<String, String, String>> streamMessageListenerContainerOptions = StreamMessageListenerContainer.StreamMessageListenerContainerOptions
.builder()
.batchSize(1)
.executor(this.threadPoolTaskExecutor)
.errorHandler(new ErrorHandler() {
@Override
public void handleError(Throwable t) {
log.error("pull message error",t.getMessage());
}
})
.pollTimeout(Duration.ofMinutes(1L))
.serializer(new StringRedisSerializer())
.build();
StreamMessageListenerContainer<String, MapRecord<String, String, String>> streamMessageListenerContainer = StreamMessageListenerContainer
.create(this.redisConnectionFactory, streamMessageListenerContainerOptions);
streamMessageListenerContainer.receive(Consumer.from(groupName, consumer),
StreamOffset.create(consumer, ReadOffset.lastConsumed()), this.streamMessageListener);
this.streamMessageListenerContainer = streamMessageListenerContainer;
this.streamMessageListenerContainer.start();
}
@Override
public void destroy() throws Exception {
this.streamMessageListenerContainer.stop();
}
}