首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JedisConnectionException -读取超时错误

JedisConnectionException -读取超时错误
EN

Stack Overflow用户
提问于 2019-04-30 12:01:21
回答 1查看 1.6K关注 0票数 2

我正在尝试使用Spring + ElastiCache组合连接到亚马逊网络服务Redis。Redis Cluster已启用,因此它具有Cluster Config端点,具有3个分片-每个分片有1个主节点+2个副本节点

我收到读取超时错误。

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out

AWS Redis服务器版本: 5.0.3 /群集模式:已启用/ SSL :已启用/身份验证:已启用(通过密码)

Library -- Spring-data-redis :2.1.6 redis/ jedis : 2.9.0

Telnet可通过6379个端口连接到AWS Redis所有节点和群集配置端点。

我尝试了Redisson本身,它连接到AWS Redis,没有任何问题。

所以,Redis本身没有问题,Spring Data Redis和Jedis的结合就是问题。

我的代码如下所示-

代码语言:javascript
运行
复制
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        redisClusterConfiguration.setClusterNodes(listOfRedisNode);
        redisClusterConfiguration.setPassword(passwordString);


        JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofSeconds(60));
        jedisClientConfiguration.useSsl();
        jedisClientConfiguration.usePooling();


        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisClientConfiguration.build() );
        jedisConnectionFactory.afterPropertiesSet();

        final RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        redisTemplate.setKeySerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.afterPropertiesSet();

        System.out.println(redisTemplate.getClientList().size());

        StringRedisConnection stringRedisConnectionlettuce = new DefaultStringRedisConnection(redisTemplate.getConnectionFactory().getConnection());
        final String message2 = stringRedisConnectionlettuce.echo("Hello");
        System.out.println("Hello".equals(message2));

读取超时错误-

代码语言:javascript
运行
复制
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
    at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
    at redis.clients.jedis.Protocol.process(Protocol.java:151)
    at redis.clients.jedis.Protocol.read(Protocol.java:215)
    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
    at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:239)
    at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:96)
    at redis.clients.jedis.Connection.sendCommand(Connection.java:126)
    at redis.clients.jedis.Connection.sendCommand(Connection.java:117)
    at redis.clients.jedis.BinaryClient.auth(BinaryClient.java:564)
    at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2138)
    at redis.clients.jedis.JedisClusterConnectionHandler.initializeSlotsCache(JedisClusterConnectionHandler.java:36)
    at redis.clients.jedis.JedisClusterConnectionHandler.<init>(JedisClusterConnectionHandler.java:17)
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.<init>(JedisSlotBasedConnectionHandler.java:24)
    at redis.clients.jedis.BinaryJedisCluster.<init>(BinaryJedisCluster.java:54)
    at redis.clients.jedis.JedisCluster.<init>(JedisCluster.java:93)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createCluster(JedisConnectionFactory.java:418)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createCluster(JedisConnectionFactory.java:388)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.afterPropertiesSet(JedisConnectionFactory.java:345)
    at io.github.deepshiv126.springdataredis.example.MySpringBootApplication.main(MySpringBootApplication.java:306)
    ... 8 more
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:127)
    at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)
    ... 27 more

我研究了Spring源代码和Jedis源代码--我假设它没有使用SSL连接;

JedisConnectionFactory - afterPropertiesSet()--正在尝试创建集群--它正在尝试initializeSlotsCache,它使用密码向Redis Server发出AUTH命令--这就是“读取超时”发生的地方;

我理解本地redis -您可以进入内部并运行auth命令来获取身份验证。但我猜AWS Redis可能无法做到这一点,它甚至在运行AUTH命令之前就需要有SSL连接-为什么Jedis不使用SSL连接?

这是"Cannot get Jedis connection" when using SSL with Redis and Spring Data Redis说的另一个线程,使用像JedisPool这样的东西-但是spring-data-redis的JedisConnectionFactory不接受JedisPool。有没有其他方法可以做到这一点?

JedisPool jedisPool = new JedisPool("rediss://" + clusterConfigEndPoint + ":6379");

另一个问题-其他库使用redis ssl连接作为rediss:// -如何在Jedis客户端使用SSL连接,

任何帮助都将不胜感激!

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2021-05-09 22:36:57

我已经面对这个问题很长一段时间了,然而,在下面的配置中,它与启用了SSL的AWS ElasticCache - Redis完美地兼容(启用了传输中加密和静态加密)。

下面的Maven依赖项用作springboot应用程序的一部分

代码语言:javascript
运行
复制
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- Latest jedis with SSL support -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.6.0</version>
        </dependency>

@Component
public class RedisConfig {

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {

        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName("PrimaryEndpoint of AWS Elastic Cache Cluster");
        redisStandaloneConfiguration.setPort(6379);
        redisStandaloneConfiguration.setUsername("userName");
        
        redisStandaloneConfiguration.setPassword(new String("password").toCharArray());

        JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofSeconds(60));// 60s connection timeout
        jedisClientConfiguration.useSsl();
        jedisClientConfiguration.usePooling();

        JedisConnectionFactory jedisConFactory = new JedisConnectionFactory(redisStandaloneConfiguration,
                jedisClientConfiguration.build());
        jedisConFactory.afterPropertiesSet();

        return jedisConFactory;
    }

    @Bean(value = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55913795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档