代码之家  ›  专栏  ›  技术社区  ›  Alexey Alexeenka

谷歌云内存商店(Redis),实例刚启动时无法连接到Redis

  •  0
  • Alexey Alexeenka  · 技术社区  · 7 年前

    当我的实例刚刚启动时,连接到redis时出现问题。

    我使用:

    runtime: java
    env: flex
    
    runtime_config:  
      jdk: openjdk8
    

    Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
    
    RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    
    java.net.SocketTimeoutException: connect timed out
    

    2-3分钟后,它开始工作

    附笔

    @Value("${spring.redis.host}")
    private String redisHost;
    
    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        // https://cloud.google.com/memorystore/docs/redis/quotas
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, 6379);
        return new JedisConnectionFactory(config);
    }
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(
            @Autowired JedisConnectionFactory jedisConnectionFactory
    ) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(newObjectMapper()));
        return template;
    }
    

    在pom.xml中

        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>2.1.2.RELEASE</version>
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Alexey Alexeenka    7 年前

    我解决这个问题的方法如下:简而言之,我添加了ping方法,它试图从Redis设置并获取值;如果可能,则应用程序已准备就绪。

    实施:

    第一 ,您需要更新app.yaml添加以下内容:

    readiness_check:
    path: "/readiness_check"
    check_interval_sec: 5
    timeout_sec: 4
    failure_threshold: 2
    success_threshold: 2
    app_start_timeout_sec: 300
    

    ,在rest控制器中:

    @GetMapping("/readiness_check")
    public ResponseEntity<?> readiness_check() {
    
        if (!cacheConfig.ping()) {
            return ResponseEntity.notFound().build();
        }
    
        return ResponseEntity.ok().build();
    }
    

    第三 ,类CacheConfig:

    public boolean ping() {
        long prefix = System.currentTimeMillis();
        try {
            redisTemplate.opsForValue().set("readiness_check_" + prefix, Boolean.TRUE, 100, TimeUnit.SECONDS);
            Boolean val = (Boolean) redisTemplate.opsForValue().get("readiness_check_" + prefix);
            return Boolean.TRUE.equals(val);
        } catch (Exception e) {
            LOGGER.info("ping failed for " + System.currentTimeMillis());
            return false;
        }
    }
    

    附笔。 另外,如果有人需要完全实现CacheConfig:

    @Configuration
    public class CacheConfig {
    
        private static final Logger LOGGER = Logger.getLogger(CacheConfig.class.getName());
    
        @Value("${spring.redis.host}")
        private String redisHost;
    
        private final RedisTemplate<String, Object> redisTemplate;
    
        @Autowired
        public CacheConfig(@Lazy RedisTemplate<String, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    
        @Bean
        JedisConnectionFactory jedisConnectionFactory(
                @Autowired JedisPoolConfig poolConfig
        ) {
            // https://cloud.google.com/memorystore/docs/redis/quotas
            RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, 6379);
    
            JedisClientConfiguration clientConfig = JedisClientConfiguration
                    .builder()
                    .usePooling()
                    .poolConfig(poolConfig)
                    .build();
    
            return new JedisConnectionFactory(config, clientConfig);
        }
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(
                @Autowired JedisConnectionFactory jedisConnectionFactory
        ) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(jedisConnectionFactory);
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer(newObjectMapper()));
            return template;
        }
    
        /**
         * Example: https://github.com/PengliuIBM/pws_demo/blob/1becdca1bc19320c2742504baa1cada3260f8d93/redisData/src/main/java/com/pivotal/wangyu/study/springdataredis/config/RedisConfig.java
         */
        @Bean
        redis.clients.jedis.JedisPoolConfig jedisPoolConfig() {
            final redis.clients.jedis.JedisPoolConfig poolConfig = new redis.clients.jedis.JedisPoolConfig();
    
            // Maximum active connections to Redis instance
            poolConfig.setMaxTotal(16);
            // Number of connections to Redis that just sit there and do nothing
            poolConfig.setMaxIdle(16);
            // Minimum number of idle connections to Redis - these can be seen as always open and ready to serve
            poolConfig.setMinIdle(8);
    
            // Tests whether connection is dead when returning a connection to the pool
            poolConfig.setTestOnBorrow(true);
            // Tests whether connection is dead when connection retrieval method is called
            poolConfig.setTestOnReturn(true);
            // Tests whether connections are dead during idle periods
            poolConfig.setTestWhileIdle(true);
    
            return poolConfig;
        }
    
        public boolean ping() {
            long prefix = System.currentTimeMillis();
            try {
                redisTemplate.opsForValue().set("readiness_check_" + prefix, Boolean.TRUE, 100, TimeUnit.SECONDS);
                Boolean val = (Boolean) redisTemplate.opsForValue().get("readiness_check_" + prefix);
                return Boolean.TRUE.equals(val);
            } catch (Exception e) {
                LOGGER.info("ping failed for " + System.currentTimeMillis());
                return false;
            }
        }
    }
    
    推荐文章