Spring Boot无法连接Redis求助:连接提前关闭
无法从Spring Boot应用连接到Upstash Redis服务
我在upstash.io上拥有一个Redis服务,但Spring Boot应用无法连接到它,连接本地Redis也报相同错误:io.lettuce.core.RedisConnectionException: Connection closed prematurely,尝试增加超时时间无效。
原始Redis配置
@Configuration public class RedisConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName("myhost"); redisStandaloneConfiguration.setPort(6379); redisStandaloneConfiguration.setPassword(RedisPassword.of("password")); // Uncomment if password is needed return new LettuceConnectionFactory(redisStandaloneConfiguration); } @Bean public RedisTemplate<Object, Object> redisTemplate() { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new StringRedisSerializer()); return template; } }
Redis服务代码
@Component @RequiredArgsConstructor public class RedisService { @Autowired private final RedisTemplate<Object, Object> redisTemplate; @PostConstruct public void testConnection() { try { redisTemplate.getConnectionFactory().getConnection().ping(); System.out.println("Connected to Redis successfully"); } catch (Exception e) { System.err.println("Unable to connect to Redis: " + e.getMessage()); } } public <V> void set(String key, V value, long timeout, TimeUnit timeUnit) { System.out.println("Storing message to redis cache: Key[" + key + "]"); redisTemplate.opsForValue().set(key, value); redisTemplate.expire(key, timeout, timeUnit); } public <V> V get(String key) { return (V) redisTemplate.opsForValue().get(key); } public Boolean hasKey(String key) { return redisTemplate.hasKey(key); } }
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.springprojects</groupId> <artifactId>realtimechatapp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>realtimechatapp</name> <description>Chat Application using Spring Boot</description> <properties> <java.version>17</java.version> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>10.1.18</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity6</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <builder>paketobuildpacks/builder-jammy-base:latest</builder> </image> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> </project>
更新后的Redis配置
@Configuration public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { System.out.println("Creating RedisConnectionFactory"); return new LettuceConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { System.out.println("Creating RedisTemplate"); RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }
错误日志
Caused by: io.lettuce.core.RedisConnectionException: Connection closed prematurely
解决建议
1. 检查Redis服务状态
- 本地Redis:执行
redis-cli ping命令,确认本地Redis服务是否正常启动并能响应。 - Upstash Redis:登录Upstash控制台,确认实例处于运行状态,同时检查IP访问白名单是否包含你的应用服务器IP(若开启了IP限制)。
2. 启用SSL连接(针对Upstash)
Upstash Redis默认强制要求SSL连接,当前配置未启用SSL是常见的连接失败原因,修改连接工厂配置:
@Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); config.setHostName("你的Upstash主机地址"); config.setPort(6379); config.setPassword(RedisPassword.of("你的Upstash密码")); LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .useSsl().build(); // 启用SSL return new LettuceConnectionFactory(config, clientConfig); }
3. 修正连接工厂实例管理
原始配置中redisTemplate()直接调用redisConnectionFactory()方法,会导致创建多个连接工厂实例,改为依赖注入方式获取:
@Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; }
4. 配置文件化管理参数
推荐将Redis配置移至application.properties,避免硬编码,Spring Boot会自动完成连接工厂配置:
spring.data.redis.host=你的Upstash主机地址 spring.data.redis.port=6379 spring.data.redis.password=你的Upstash密码 spring.data.redis.ssl=true
此时可移除自定义的RedisConfig类,简化配置。
5. 清理依赖冲突
pom.xml中同时引入了io.lettuce:lettuce-core和spring-boot-starter-data-redis,后者已包含Lettuce依赖,重复引入可能导致版本冲突,建议移除单独的lettuce-core依赖。
内容的提问来源于stack exchange,提问作者Dhananjai Saini
相关产品推荐
相关产品推荐

