在 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 时才有效