Redis重返舞台:Spring Boot容器错误解决的专业魔法之旅!

文章分析了在Docker环境下SpringBoot应用连接Redis容器异常的原因,主要是网络配置和密码验证问题。通过检查容器网络、堆栈跟踪和异常信息,发现密码包含特殊字符且编码不一致可能是导致连接失败的关键。解决方案包括确保编码格式一致和正确处理特殊字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

  • 在使用容器部署springboot项目时,遇到springBoot连接redis容器异常。
  • 根据日志的堆栈跟踪信息,是由于连接Redis失败而导致的异常。堆栈跟踪显示了连接Redis时发生了io.lettuce.core.RedisConnectionException: Unable to connect to redis:6379 异常。无法连接到 Redis 服务器的地址为 “redis:6379”。

分析

网络问题分析

  • 由于项目是使用docker compose进行部署,所以,需要考虑各个容器(mysql、redis、rabbit)是否同在一个网络下,否则无法通信。
  • 查看docker_default网络下的所有容器(作者在部署容器时,并没有显式指定网络,所以这里使用默认的网络)
  • 如果默认网络名称不是 docker_default,请将命令中的网络名称替换为您实际使用的网络名称。
docker network inspect docker_default --format='{{range .Containers}}{{.Name}} - {{.IPv4Address}}{{println}}{{end}}'
  • 使用 docker network inspect 命令来检查 docker_default 网络,并使用 --format 参数来指定输出格式。
命令解释
{{range .Containers}}遍历每个容器
{{.Name}}输出容器名称
{{.IPv4Address}}输出容器的 IPv4 地址
{{println}}{{end}}用于在每个容器信息之间添加换行符。
  • 执行的结果如下:
root@armbian:/usr/local/aurora-springboot# docker network inspect docker_default --format='{{range .Containers}}{{.Name}} - {{.IPv4Address}}{{println}}{{end}}'
redis - 172.28.0.2/16
rabbitmq - 172.28.0.6/16
maxwell - 172.28.0.4/16
services - 172.28.0.5/16
elasticsearch - 172.28.0.3/16
aurora-springboot-0.0.1.jar - 172.28.0.7/16
  • aurora-springboot-0.0.1.jarredis处于同一个网络下项目启动还会提示连接不到,很懵!!!!

异常连接分析

  • 继续根据日志,分析错误
    (String), 192.168.1.9(String), 内网IP|内网IP(String), 2023-06-23T13:51:00.567(LocalDateTime)
    Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to redis:6379
    	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
    	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
    	at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:242)
    	at io.lettuce.core.RedisClient.connect(RedisClient.java:206)
    	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115)
    	at java.util.Optional.orElseGet(Optional.java:267)
    	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115)
    	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$null$0(LettucePoolingConnectionProvider.java:97)
    	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:211)
    	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:201)
    	at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:58)
    	at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:899)
    	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:429)
    	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:354)
    	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:122)
    	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:117)
    	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:103)
    	... 20 more
    Caused by: io.lettuce.core.RedisCommandExecutionException: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?
    	at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:135)
    	at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:108)
    	at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:118)
    	at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:109)
    	at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:680)
    	at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:640)
    	at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:591)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    	at java.lang.Thread.run(Thread.java:748)
    <==    Updates: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2fec2f1a]
    
  • 连接 Redis 时发生了身份验证错误。 错误消息表明 Redis 客户端尝试使用身份验证密码进行连接,但 Redis 服务器未配置密码或密码配置不正确。错误消息中显示以下内容:
    Caused by: io.lettuce.core.RedisCommandExecutionException: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?
    

要解决此问题,请确保:

  1. 确保 Redis 服务器已配置身份验证密码。

  2. 使用正确的密码进行 Redis 连接。检查项目配置文件使用的是正确的密码。即: Spring Boot 的配置文件(application.properties 或 application.yml)中添加以下配置内容:

    • 对于 application.properties:
    spring.redis.password=your_redis_password
    
    • 对于 application.yml:
    spring:
      redis:
        password: your_redis_password
    
  3. 经过检查和测试,已经正确配置密码但仍然无法连接,那一定是密码中存在特殊字符或转义字符,与 Redis 服务器的配置不完全匹配。


  • 回顾过去的操作,项目配置文件是在win环境下编写,docker compose是在linux系统环境下,编辑。两者使用不通的文件编码格式,可能会造成连接密码验证错误。

  • 在编写 Docker Compose 文件时使用的是 UNIX 编码,而项目开发使用的是 UTF-8 编码,并且 Redis 连接密码包含特殊字符(如 .),那么连接时可能会出现问题。在 Docker Compose 文件中,密码作为环境变量的值进行配置。如果密码包含特殊字符,并且编码方式不一致,可能导致密码在解析时出现错误或无法正确匹配。

  • 为了避免这种情况,建议在编写 Docker Compose 文件时使用与项目开发一致的编码方式(如 UTF-8),以确保密码能够正确解析和匹配。

分析结果

  • 密码包含特殊字符,并且由于编码方式不一致而导致连接问。

解决方法

尝试以下解决方法:

  1. 使用与项目开发一致的编码方式编写 Docker Compose 文件,例如使用 UTF-8 编码。
  2. 如果密码中包含特殊字符,可以尝试使用转义序列或编码方式来表示这些字符。例如,对于 . 可以使用 \. 或者 %2E 来表示。
  3. 在项目中连接 Redis 时,确保使用与 Docker Compose 文件中密码配置相匹配的密码,并且处理特殊字符的转义或解码。
  • 通过保持编码方式一致并正确处理特殊字符,您应该能够避免由于编码不一致而导致的连接问题。

验证分析

  • 重新使用utf-8编辑docker compose文件,然后重现部署容器和项目,正常连接。

反思和求知

  1. 在linux文件中创建的docker compose文件使用utf-8编码格式,能正常执行部署吗?
    • 在 Linux 系统上创建的Docker Compose 文件使用 UTF-8 编码格式是可以正常执行的。Docker Compose 文件是一个纯文本文件,它的编码方式并不会影响 Docker Compose 的执行。Docker Compose 工具会读取该文件并解析其中的配置信息来创建和管理容器。只要文件的内容符合正确的 Docker Compose 语法,并且所使用的编码方式是有效的,就可以正常执行。
    • 无论是在 WindowsLinux 还是其他操作系统上创建 Docker Compose 文件,只要保证文件的编码方式正确,并且文件内容没有语法错误,就可以顺利使用 Docker Compose 工具进行部署和管理容器。
  • 因此 , 在 Linux 系统上使用 UTF-8 编码格式创建Docker Compose 文件,而不会对执行产生任何影响。

  1. 使用docker compose在进行部署的时候,如何实现不同编码格式的文件(如 utf-8unix)的正常使用?
    • 在进行 Docker Compose 部署时,确保不同编码格式的文件(如 UTF-8Unix)的正常使用,需要注意以下几点:
    1. 文件编码保持一致:确保 Docker Compose 文件及其相关的配置文件在创建和编辑时,都使用相同的编码格式。最常见的选择是使用 UTF-8 编码,因为它支持广泛的字符集和多种语言。

    2. 文本编辑器选择:使用支持多种编码格式的文本编辑器来编辑 Docker Compose 文件。现代的文本编辑器通常支持自动检测编码,并能够灵活地保存不同的编码格式。

    3. 避免特殊字符:在 Docker Compose 文件中,尽量避免使用特殊字符,因为不同编码格式对特殊字符的处理可能不同,导致解析错误。

    4. 字符转义:如果 Docker Compose 文件中包含一些特殊字符或非ASCII字符,确保它们被正确地转义,以免出现解析问题。

    5. 测试部署:在部署之前,先进行测试。使用 docker-compose config 命令来检查 Docker Compose 文件的语法是否正确,这可以避免因编码问题导致的语法错误。

    6. 使用统一的编码格式:为了降低混淆和错误的风险,建议在整个团队或项目中都采用统一的编码格式,通常推荐使用 UTF-8 编码。

  • 总的来说,遵循统一的编码规范,并选择支持多种编码格式的文本编辑器,能够确保 Docker Compose 文件的正确解析和正常部署。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值