在Redis和Spring Data Redis中使用SSL时“无法获得Jedis连接”

时间:2018-01-29 03:26:03

标签: spring ssl redis

我正在使用启用SSL的Redis(来自AWS的ElasticCache),并且难以使用Spring Data Redis连接到它。

(请注意,如果我使用普通的Jedis或带有Spring的Jedis Pool,连接工作正常。)

以下是代码段:

    @Value("${vcap.services.myredis.credentials.host}")
    private String redisHost;

    @Value("${vcap.services.myredis.credentials.password}")
    private String redisPassword;

    @Value("${vcap.services.myredis.credentials.port}")
    private String redisPort;

    public RedisTemplate<String, Object> redisTemplate() {

        final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();


        String hostUri = "rediss://:" + redisPassword + "@" + redisHost + redisPort;    

        JedisShardInfo info = new JedisShardInfo(hostUri);

        JedisConnectionFactory conn =  new JedisConnectionFactory(info);

        conn.afterPropertiesSet();

        template.setConnectionFactory(conn);
        template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class));
        return template;
    }

}

RedisTemplate用法:

    @Autowired
    private RedisTemplate<String, String> redistemplate;


    public void api2() {

        HashOperations<String, Object, Object> hashOperations = redistemplate.opsForHash();

        hashOperations.put("KEY", "1", "one"); 
    }

}

使用RedisTemplate的任何操作都会抛出异常:

  

“嵌套异常是   org.springframework.data.redis.RedisConnectionFailureException:不能   获得Jedis连接;嵌套异常是   redis.clients.jedis.exceptions.JedisConnectionException:无法获取   具有根本原因的来自池的资源   2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0] [OUT]   java.net.SocketException:连接重置   2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0] [OUT] at   java.net.SocketInputStream.read(SocketInputStream.java:210)   〜[na:1.8.0_141] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0] [OUT]   在java.net.SocketInputStream.read(SocketInputStream.java:141)   〜[na:1.8.0_141] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0] [OUT]   在java.net.SocketInputStream.read(SocketInputStream.java:127)   〜[na:1.8.0_141] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0] [OUT]   在   redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at   redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at redis.clients.jedis.Protocol.process(Protocol.java:151)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at redis.clients.jedis.Protocol.read(Protocol.java:215)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at   redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at   redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:239)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2139)   〜[jedis-2.9.0.jar!/:na] 2018-01-22T15:59:35.531 + 11:00 [APP / PROC / WEB / 0]   [OUT] at   redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:108)   〜[!jedis-2.9.0.jar /:NA]“

注意:

  1. 这不是SSL Certs的问题,因为AWS的SSL证书已存在于JVM Trust存储中,请注意JedisPool正在使用SSL。

  2. 我怀疑JedisConnectionFactory以某种方式忽略并且没有建立SSL连接。我尝试了JedisConnectionFactory的其他arg构造函数,比如将useSSL设置为true等,没有运气。

  3. 感谢任何帮助或指示。

3 个答案:

答案 0 :(得分:0)

不要使用JedisShardInfo,因为它会导致其携带的配置含糊不清。接受JedisShardInfo的构造函数在Spring Data Redis 2.0中已弃用。请改用基于属性的配置:

JedisConnectionFactory conn =  new JedisConnectionFactory();
conn.setHostName(redisHost);
conn.setPort(redisPort);
conn.setUseSsl(true);

答案 1 :(得分:0)

我遇到了类似的问题,但问题是JedisPool,而不是SpringJedisShardInfo。我相信,这基本上是同一个问题。连接到启用了SSL的AWS Elasticache redis群集时,我会得到一个

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset

解决了我的问题是使用jedis 2.9.0并启动JedisPool这样的问题:

String host = "someHost"; // The primary endpoint of the cluster
JedisPool jedisPool = new JedisPool("rediss://" + host + ":6379");

在此处使用String构造函数非常重要,因为URI无法启用SSL。

答案 2 :(得分:0)

您只提到了AWS Elastic Redis,但没有指定它是基于集群的Redis还是单节点Redis?

Spring Data Redis 2.2将支持SSL群集。 https://jira.spring.io/browse/DATAREDIS-974