Docker部署Redis与Spring Boot集成连接失败问题求助
我之前也踩过Spring Boot + Docker Redis连接的各种坑,结合你的情况,给你梳理一套逐步排查和解决的思路:
一、先确认Docker Redis的基础网络配置是否正常
这是最容易被忽略的环节,先排除Redis容器本身的问题:
- 检查端口映射:确保启动Redis容器时加了端口映射命令,比如
docker run -d -p 6379:6379 --name my-redis redis。如果没加-p 6379:6379,宿主机根本无法访问容器内的Redis服务。 - 手动验证连接:在宿主机终端用
redis-cli -h 192.168.99.100 -p 6379尝试连接,如果连不上,直接跳过Spring Boot排查,先解决Docker Redis的网络问题:- 检查容器是否正常运行:
docker ps,看my-redis容器状态是不是Up - 确认Redis绑定的是
0.0.0.0:进入容器执行redis-cli config get bind,返回1) "bind" 2) "0.0.0.0"就是正确的,允许所有IP访问
- 检查容器是否正常运行:
- 注意Docker网络环境:如果用的是Docker Toolbox(旧版Windows/macOS环境),192.168.99.100是Docker Machine的虚拟IP,要确保这个IP能被宿主机ping通,且容器端口确实映射到了这个IP上。
二、核对Spring Boot配置的有效性
确认Redis容器没问题后,检查Spring Boot的配置是否真的生效:
- 检查配置键是否正确:Spring Boot 2.x的Redis配置前缀是
spring.redis,你的application.properties应该是这样:spring.redis.host=192.168.99.100 spring.redis.port=6379 # 如果Redis设置了密码,一定要加上下面这行 # spring.redis.password=your-redis-password - 验证配置是否加载:在启动类里加一段代码,打印读取到的Redis配置,确认不是默认的localhost:
如果输出还是@SpringBootApplication public class YourApplication { @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private int redisPort; public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } @PostConstruct public void printRedisConfig() { System.out.println("当前加载的Redis配置:host=" + redisHost + ", port=" + redisPort); } }localhost:6379,说明配置文件没被正确加载——检查配置文件是否放在src/main/resources下,或者是否存在多配置文件优先级覆盖的问题(比如application-dev.properties覆盖了主配置)。
三、Lettuce客户端的配置细节排查
你手动构建LettuceConnectionFactory仍失败,可能是配置代码有遗漏:
- 确保自定义ConnectionFactory被正确使用:你的RedisConfig要完整配置,并且保证RedisTemplate、RedisMessageListenerContainer都依赖这个自定义的Factory:
关键点:不要让Spring Boot自动生成默认的ConnectionFactory,确保所有Redis相关组件都用你自定义的这个。@Configuration public class RedisConfig { @Value("${spring.redis.host}") private String redisHost; @Value("${spring.redis.port}") private int redisPort; // 如果有密码,加上这个 // @Value("${spring.redis.password}") // private String redisPassword; @Bean public LettuceConnectionFactory lettuceConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, redisPort); // 有密码的话开启下面一行 // config.setPassword(RedisPassword.of(redisPassword)); // 可以加连接超时配置,避免因网络延迟导致连接失败 LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .connectTimeout(Duration.ofSeconds(10)) .build(); return new LettuceConnectionFactory(config, clientConfig); } @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); // 配置序列化(可选,但建议加上,避免乱码) template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } // 如果用了RedisMessageListenerContainer,手动注入自定义的ConnectionFactory @Bean public RedisMessageListenerContainer messageListenerContainer(LettuceConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); // 这里添加你的监听器配置 return container; } }
四、Jedis客户端的补充排查(如果需要切换回去)
如果还要用Jedis,注意依赖和配置的细节:
- 排除Lettuce依赖:在pom.xml里排除Spring Boot默认的Lettuce,引入Jedis:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> - 配置Jedis连接池:Jedis默认是单连接,加上连接池配置能避免很多连接超时问题:
@Bean public JedisConnectionFactory jedisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisHost, redisPort); JedisClientConfiguration jedisConfig = JedisClientConfiguration.builder() .connectTimeout(Duration.ofSeconds(5)) .usePooling() .poolConfig(new JedisPoolConfig()) .build(); return new JedisConnectionFactory(config, jedisConfig); }
五、最后检查防火墙
宿主机的防火墙可能会拦截6379端口:
- Ubuntu系统:执行
sudo ufw allow 6379/tcp && sudo ufw reload - CentOS/RHEL系统:执行
sudo firewall-cmd --add-port=6379/tcp --permanent && sudo firewall-cmd --reload
内容的提问来源于stack exchange,提问作者skyho




