[英]JedisConnectionException - Read timed out error
我正在嘗試使用 Spring Data Redis + Jedis 組合連接到 AWS ElastiCache Redis。 [Redis 集群啟用,所以它有集群配置端點,有 3 個分片 - 每個分片有 1 個主節點 + 2 個副本節點]
我收到讀取超時錯誤。
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
AWS Redis 服務器版本:5.0.3/集群模式:啟用/SSL:啟用/身份驗證:啟用(通過密碼)
庫 -- Spring-data-redis : 2.1.6.Release / jedis : 2.9.0
Telnet 在 6379 個端口上適用於 AWS Redis 所有節點和集群配置端點。
我自己嘗試了 Redisson,它可以連接到 AWS Redis,沒有任何問題。
所以,Redis 本身沒有問題,Spring Data Redis 與 Jedis 結合的問題。
我的代碼看起來像這樣 -
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));
讀取超時錯誤 -
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()-- 嘗試創建集群 - 在此情況下,它正在嘗試使用密碼向 Redis 服務器發出 AUTH 命令的 initializeSlotsCache - 這就是發生“讀取超時”的地方;
我了解本地 redis - 您可以進入並運行 auth 命令以進行身份驗證。 但我猜 AWS Redis 可能無法做到這一點,它甚至在運行 AUTH 命令之前就需要有 SSL 連接 - 為什么 Jedis 不使用 SSL 連接?
當將 SSL 與 Redis 和 Spring Data Redis 一起使用時,另一個線程“無法獲得 Jedis 連接”說,使用類似 JedisPool 的東西 - 但 spring-data-redis 的 JedisConnectionFactory 不接受 JedisPool。 有沒有其他方法可以做到這一點?
JedisPool jedisPool = new JedisPool("rediss://" + clusterConfigEndPoint + ":6379");
另一個問題 - 其他庫使用 redis ssl 連接作為rediss://
- 如何讓 Jedis Client 使用 SSL 連接,
任何幫助將不勝感激!
謝謝!
我面對這個問題已經有一段時間了,但是通過以下配置,它可以與 AWS ElasticCache 完美配合 - Redis 啟用 SSL(傳輸中加密和靜態加密啟用)。
以下 Maven 依賴項用作 springboot 應用程序的一部分
<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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.