Spring应用Docker容器内反复出现UnknownHostException的排查方向咨询
这种DNS解析失效的问题我在Docker+Spring的生产环境里碰到过好几次,给你整理几个最可能的原因和对应的解决思路:
可能的原因及解决方案
1. Docker内置DNS缓存老化/耗尽
Docker默认的DNS缓存机制在容器长期运行后,可能会因为缓存条目过期或资源耗尽导致解析失败。
- 解决办法:
- 给容器指定公共DNS服务器,绕过Docker默认DNS。启动容器时添加参数:
docker run --dns 8.8.8.8 --dns 8.8.4.4 [你的容器镜像] - 或者修改Docker全局DNS配置,编辑
/etc/docker/daemon.json:
保存后执行{ "dns": ["8.8.8.8", "8.8.4.4"] }sudo systemctl restart docker生效。
- 给容器指定公共DNS服务器,绕过Docker默认DNS。启动容器时添加参数:
2. Java自身DNS缓存滞留
Java默认会缓存域名解析结果,且TTL值较长。如果目标域名的IP发生变更,应用可能还在使用旧的缓存IP,导致UnknownHostException。
- 解决办法:
- 通过JVM启动参数缩短缓存时间:
前者是成功解析的域名缓存时长(秒),后者是解析失败的缓存时长,缩短后能更快获取新IP。java -Dsun.net.inetaddr.ttl=60 -Dsun.net.inetaddr.negative.ttl=10 -jar [你的应用jar包] - 也可以在应用代码里动态设置:
java.security.Security.setProperty("networkaddress.cache.ttl", "60"); java.security.Security.setProperty("networkaddress.cache.negative.ttl", "10");
- 通过JVM启动参数缩短缓存时间:
3. Docker网络资源耗尽
长期运行的容器可能会耗尽网络相关的系统资源(比如文件句柄),导致DNS解析无法正常进行。
- 解决办法:
- 启动容器时增加文件句柄上限:
docker run --ulimit nofile=65535:65535 [你的容器镜像] - 配置容器健康检查,自动重启故障容器。在
docker-compose.yml中添加:
当连续3次解析失败时,Docker会自动重启容器。services: your-app: image: [你的镜像] healthcheck: test: ["CMD", "nslookup", "api.bankoncube.com", "||", "exit", "1"] interval: 30s timeout: 10s retries: 3 start_period: 60s
- 启动容器时增加文件句柄上限:
4. Docker DNS服务异常
Docker的内置DNS服务在长期运行后可能出现异常,导致容器无法正常解析域名。
- 解决办法:
- 重启Docker服务临时恢复:
sudo systemctl restart docker - 检查Docker日志排查DNS服务故障:
sudo journalctl -u docker.service
- 重启Docker服务临时恢复:
内容的提问来源于stack exchange,提问作者Shashank Singh
相关产品推荐
相关产品推荐

