Spring-data-redis Jedis RedisMessageListenerContainer - 发生连接失败 5000 毫秒后重新启动订阅任务

问题描述

在这里发现了一些类似的问题,但解决方案没有解决我的问题,我的消息侦听器(订阅)配置似乎有误。

我对 redis 很陌生,我想列出/读取/订阅一个没有任何密码的现有 redis 服务器。

我可以在本地通过 redis-cli 监听该服务器,但是当我尝试向 Spring Boot 应用程序添加 redis 监听器时,消息监听器容器似乎无法建立连接。

我收到这条重复消息:

2021-01-18 22:12:32 [redisContainer-31] ERROR o.s.d.r.l.RedisMessageListenerContainer -Connection failure occurred. Restarting subscription task after 5000 ms

以下是关于我如何将 spring-data-redis (2.3.3.RELEASE) + jedis (2.10.0) spring boot 添加到我的应用程序的一些片段。

pom.xml

  ...
  <properties>
    ...
    <redis.version>2.3.3.RELEASE</redis.version>
    <jedis.version>2.10.0</jedis.version>
  </properties>

  <dependencies>
    ...  
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <version>${redis.version}</version>
    </dependency>
    <!-- There is no redis.clients.util.SafeEncoder class deFinition in version 3.1.0 -->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>${jedis.version}</version>
    </dependency>
  </dependencies>
  ...

application.properties

# Redis
spring.redis.database=0
spring.redis.host=sabong-dev.abs3252.8888.use69.cache.amazonaws.com
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=60000
spring.redis.channel.sabongEvents=SABONG_EVENTS

请注意,连接现有的redis服务器没有密码,我可以使用SABONG_EVENTS在本地读取/监听redis-cli

RedisConfig.java

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private Integer redisPort;

    @Value("${spring.redis.channel.sabongEvents}")
    private String channelTopic;

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisHost,redisPort);
        return new JedisConnectionFactory(redisStandaloneConfiguration);
    }

    @Bean
    public Redistemplate<String,Object> redistemplate() {
        Redistemplate<String,Object> template = new Redistemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }

    @Bean
    MessageListenerAdapter messageListener() {
        return new MessageListenerAdapter(new MyRedisMessageSubscriber());
    }

    @Bean
    RedisMessageListenerContainer redisContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(jedisConnectionFactory());
        container.addMessageListener(messageListener(),channelTopic());
        return container;
    }

    @Bean
    ChannelTopic channelTopic() {
        return new ChannelTopic(channelTopic);
    }

}

MyRedisMessageSubscriber.java

package package.my.sample;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;

...

@Service
public class RedisMessageSubscriber implements MessageListener {

    private static final Logger logger = LoggerFactory.getLogger(MyRedisMessageSubscriber.class);

    public void onMessage(Message message,byte[] pattern) {
        String msg = message.toString();
        logger.info("\n[topic-message]: {}\n",msg);
    }

}

我不确定我的代码有什么问题,我知道这很简单,因为我只想显示 sysout/logger.info 我从 redis 频道收到的消息。

应用程序运行但无法建立连接以进行读/听。

我可能在这里遗漏了一些代码或配置,但我不确定在哪里或什么。

谢谢!

更新(解决方案) 似乎 spring-boot 没有自动设置我的 redis 主机和端口,可能是因为我错过了一些东西或一些错误属性名称导致它没有自动设置。

在我的 redis 配置类中,我使用 JedisConnectionFactory 在我的 RedisStandaloneConfiguration 中设置了 redis 主机和端口。由于我的问题只是建立到我的消息侦听器容器的连接..它能够使用此示例连接到我的外部 redis 服务器。

我没有删除这篇文章,而是用答案更新了它,因为我知道我可能会再次需要这个,因为我很健忘:)

解决方法

调试后发现我的配置属性好像不行

spring.redis.host=sabong-dev.abs3252.8888.use69.cache.amazonaws.com
spring.redis.port=6379

我期待 spring boot 会为我设置这些属性值。 在我调试时,JedisConnectionFactory 仍然指向 localhost6379。端口没有问题,因为它与我期望的值相同,但 localhost 似乎是默认值,而不是我设置或期望的值。

因此为了设置主机/端口,因为 JedisConnectionFactory.setHost(host)JedisConnectionFactory.setPort(port) 已被弃用,我使用 RedisStandaloneConfiguration 来设置主机和端口,并在 {{1} 的构造函数中使用它}.所以它看起来像这样。

RedisConfig.java

JedisConnectionFactory

在设置正确的主机(和端口)后,它能够与我的 redis 服务器和通道建立连接。

同样,我的问题是我的消息侦听器容器出现连接问题,主要问题是... spring-boot 没有自动设置我的 redis 主机和端口。我知道我的属性可能存在一些错误,导致 spring-boot 无法正确设置。但这个想法是,一旦我设置了 redis 主机和端口,我就能够连接到我的服务器,并且我能够读取/收听我设置的频道。

我会更新我的原始帖子并修复代码