在 localhost 上运行的 Spring Boot 应用程序无法与在 docker 上运行的 redis 通信

Posted

技术标签:

【中文标题】在 localhost 上运行的 Spring Boot 应用程序无法与在 docker 上运行的 redis 通信【英文标题】:Springboot app running on localhost cant communicate with redis running on docker 【发布时间】:2021-10-28 19:37:32 【问题描述】:

我有一个可以在 localhost 上正常运行的 Spring Boot 应用程序。但是,我最近决定添加缓存,并从 docker 运行我的 Redis 服务器。我现在面临的问题是我的 Springboot 应用程序无法与我在 docker 上运行的 Redis 通信。我得到如下错误:

 2021-08-29 23:51:22.435 ERROR 24319 --- [0.1-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to redis/<unresolved>:6379] with root cause

java.net.UnknownHostException: redis: nodename nor servname provided, or not known
    at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) ~[na:na]
    at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:932) ~[na:na]
    at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1517) ~[na:na]
    at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:851) ~[na:na]
    at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1507) ~[na:na]
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1366) ~[na:na]
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1300) ~[na:na]
    at java.base/java.net.InetAddress.getByName(InetAddress.java:1250) ~[na:na]
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:156) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:153) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:554) ~[na:na]
    at io.netty.util.internal.SocketUtils.addressByName(SocketUtils.java:153) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.DefaultNameResolver.doResolve(DefaultNameResolver.java:41) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:61) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:53) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:55) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:31) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.resolver.AbstractAddressResolver.resolve(AbstractAddressResolver.java:106) ~[netty-resolver-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:206) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:46) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:180) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:166) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:1012) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:516) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.65.Final.jar:4.1.65.Final]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:an]

以下是我的 application.properties 文件中的内容

server.port=8080
server.address=localhost
management.endpoints.enabled-by-default= false
management.endpoint.health.enabled=true
springdoc.swagger-ui.disable-swagger-default-url=true

spring.cache.type=redis
spring.redis.host=redis
spring.redis.port=6379
spring.cache.redis.cache-null-values=false
spring.cache.redis.time-to-live=60000
spring.cache.redis.use-key-prefix=true
spring.cache.redis.key-prefix=digicore

谁能解释一下我可能做错了什么,或者我是否缺少任何文件或配置。是不是不能在本地运行springboot app,在docker上运行redis?

【问题讨论】:

如何测试 docker 中的 redis 在 6379 上是否可用? 【参考方案1】:

在错误信息中:java.net.UnknownHostException: redis

redis 不是 docker 之外的已知主机名,但是如果你暴露了端口 6379,你可以在 localhost 上使 redis 可用:spring.redis.host=localhost

确保将端口 6379 映射到 docker 端 (-p 6379:6379)。 您可以通过以下方式对其进行测试:telnet localhost 6379

【讨论】:

他还可以使用redis 主机名来确保安全,并创建一个连接它们的docker网络,这样redis实例就不会无缘无故地暴露给外界 非常感谢。我不敢相信我错过了。【参考方案2】:

感谢@Jonatan Ivanov,我做了以下更改:

    spring.redis.host 的值更改为localhost 而不是redis 在我的终端命令中添加了绑定端口,所以我的新命令如下所示:docker run --name DigicoreRedis -p 6379:6379 -d redis

【讨论】:

以上是关于在 localhost 上运行的 Spring Boot 应用程序无法与在 docker 上运行的 redis 通信的主要内容,如果未能解决你的问题,请参考以下文章

从 Node Js 重定向到 Spring 引导服务并发送回响应

使用 nginx 代理的带有 keycloak 的 Spring Boot 仅在 redirect_uri localhost 时才有效

Vue + Spring:没有通过 CORS 测试

Spring Framework 中的 Localhost 与 127.0.0.1

如何使用spring boot和angular 2登录

AWS 可以与 Spring Boot 和 React 一起使用吗?