【问题标题】:Spring Boot Redis configuration not workingSpring Boot Redis 配置不起作用
【发布时间】:2017-10-08 07:45:31
【问题描述】:

我正在开发一个带有 ServletInitializer 的 Spring Boot [web] REST 样式应用程序(因为它需要部署到现有的 Tomcat 服务器)。它有一个 @RestController 和一个方法,当调用该方法时,需要写入 Redis pub-sub channel。我在 localhost 上运行 Redis 服务器(默认端口,无密码)。 POM 文件的相关部分具有所需的启动器依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

当我部署 WAR 并点击端点 http://localhost:8080/springBootApp/health 时,我得到以下响应:

{
  "status": "DOWN",
  "diskSpace": {
    "status": "UP",
    "total": 999324516352,
    "free": 691261681664,
    "threshold": 10485760
  },
  "redis": {
    "status": "DOWN",
    "error": "org.springframework.data.redis.RedisConnectionFailureException: java.net.SocketTimeoutException: Read timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out"
  }
}

我在我的 Spring Boot 应用程序类中添加了以下内容:

@Bean
JedisConnectionFactory jedisConnectionFactory() {
    return new JedisConnectionFactory();
}

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

在执行一些测试 Redis 代码之前,我还尝试将以下内容添加到我的 @RestController,但我在堆栈跟踪中得到与上面相同的错误:

@Autowired
private RedisTemplate<String, String> redisTemplate;

编辑 (2017-05-09) 我的理解是 Spring Boot Redis starter 假定默认值为spring.redis.host=localhostspring.redis.port=6379,我仍然将这两个添加到application.properties,但这并没有填补空白。

更新 (2017-05-10) 我在这个帖子中添加了一个答案。

【问题讨论】:

    标签: java spring-boot redis


    【解决方案1】:

    我用redis和spring boot做了一个简单的例子

    首先我在docker上安装了redis:

    $ docker run --name some-redis -d redis redis-server --appendonly yes

    然后我将此代码用于接收器:

    import java.util.concurrent.CountDownLatch;
    
    public class Receiver {
        private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
    
        private CountDownLatch latch;
    
        @Autowired
        public Receiver(CountDownLatch latch) {
            this.latch = latch;
        }
    
        public void receiveMessage(String message) {
            LOGGER.info("Received <" + message + ">");
            latch.countDown();
        }
    
    }
    

    这是我的 Spring Boot 应用和我的监听器:

    @SpringBootApplication
    // after add security library then it is need to use security configuration.
    @ComponentScan("omid.spring.example.springexample.security")
    public class RunSpring {
        private static final Logger LOGGER = LoggerFactory.getLogger(RunSpring.class);
    
    
        public  static   void main(String[] args) throws InterruptedException {
            ConfigurableApplicationContext contex =  SpringApplication.run(RunSpring.class, args);
        }
    
        @Autowired
        private ApplicationContext context;
    
        @RestController
        public class SimpleController{
    
            @RequestMapping("/test")
            public String getHelloWorld(){
    
                StringRedisTemplate template = context.getBean(StringRedisTemplate.class);
                CountDownLatch latch = context.getBean(CountDownLatch.class);
    
                LOGGER.info("Sending message...");
    
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0 ;  i < 100 ; i++) {
                            template.convertAndSend("chat", i + " => Hello from Redis!");
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
    
                        }
    
                    }
                });
                t.start();
    
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
    
                return "hello world 1";
            }
        }
    
        ///////////////////////////////////////////////////////////////
    
    
        @Bean
        RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                MessageListenerAdapter listenerAdapter) {
    
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
    
            return container;
        }
    
        @Bean
        MessageListenerAdapter listenerAdapter(Receiver receiver) {
            return new MessageListenerAdapter(receiver, "receiveMessage");
        }
    
        @Bean
        Receiver receiver(CountDownLatch latch) {
            return new Receiver(latch);
        }
    
        @Bean
        CountDownLatch latch() {
            return new CountDownLatch(1);
        }
    
        @Bean
        StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
            return new StringRedisTemplate(connectionFactory);
        }
    }
    

    重点是redis的IP。如果你像我一样把它安装在 docker 上 您应该像这样在 application.properties 中设置 IP 地址: spring.redis.host=172.17.0.4

    我把我所有的spring例子都放在了github上here

    另外我使用redis stat来监控redis。这是简单的监控。

    【讨论】:

      【解决方案2】:

      你需要使用application.properties配置你的redis服务器信息:

      # REDIS (RedisProperties)
      spring.redis.cluster.nodes= # Comma-separated list of "host:port"
      spring.redis.database=0 # Database index
      spring.redis.url= # Connection URL, 
      spring.redis.host=localhost # Redis server host.
      spring.redis.password= # Login password of the redis server.
      spring.redis.ssl=false # Enable SSL support.
      spring.redis.port=6379 # Redis server port.
      

      Spring 数据文档:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html#REDIS

      【讨论】:

      • 由于我在本地使用 Redis(全新安装,没有配置更改),我认为 Spring Boot Redis starter 假定了这些默认值。我没有使用集群。唯一适用的 Redis 属性是 spring.redis.host (localhost) 和 spring.redis.port (6379)。
      • 你的 redis 服务是否正在运行。你能通过redis-cli连接服务吗?您的代码看起来不错...
      • 嗨@PraneethRamesh我的redis服务器正在运行。我运行的验证包括telnet localhost 6379 (能够远程登录到该端口) 并在控制器中编写基于 GET 的测试方法以使用Socket s = new Socket("localhost", 6379); return s.isConnected(); 打开套接字(结果为真)。所以我知道 Redis 正在运行并且可供 JVM 访问。是的,我可以使用 redis-cli 连接到服务。
      【解决方案3】:

      这是一个与代理相关的问题,甚至连对 localhost 的访问都被限制了。禁用代理设置后,Redis 运行状况为UP!所以问题就解决了。我不必向application.properties 添加任何属性,也不必在 Spring Boot 应用程序类中显式配置任何内容,因为 Spring Boot 和 Redis Starter 基于 Redis 默认值自动配置(适用于我的开发环境) .我刚刚在pom.xml 中添加了以下内容:

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      

      以及 @RestController 注释类的以下内容,并且 Spring Boot 会根据需要自动连接(太棒了!)。

      @Autowired
      private RedisTemplate<String, String> redisTemplate;
      

      要将简单的消息发布到通道,这行代码就足以验证设置:

      this.redisTemplate.convertAndSend(channelName, "hello world");
      

      感谢所有帮助我备份支票的 cmets。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        • 1970-01-01
        • 2019-02-04
        • 2019-08-25
        • 2015-04-26
        • 1970-01-01
        • 2017-05-05
        相关资源
        最近更新 更多