使用TestContainers测试Kafka Streams应用时DNS解析失败问题
核心问题背景
同一Docker网络内,被测Streams应用容器通过wget kafka能正常解析到Kafka容器的IP,但Kafka Admin客户端却抛出Couldn't resolve server PLAINTEXT://kafka:9092 from bootstrap.servers as DNS resolution failed for kafka错误,排除Docker网络连通性问题,问题出在Kafka客户端或JVM的DNS解析逻辑上。
具体解决步骤
调整JVM DNS缓存策略
Kafka客户端基于JVM运行,JVM默认的DNS缓存可能导致解析结果未及时更新。在被测应用的JVM启动参数中添加以下配置,缩短缓存有效期:-Dnetworkaddress.cache.ttl=60 -Dnetworkaddress.cache.negative.ttl=10前者设置正缓存存活时间为60秒,后者设置解析失败的负缓存为10秒,强制JVM更快刷新DNS解析结果。
直接使用Kafka容器IP作为Bootstrap地址
既然wget kafka能获取到Kafka容器的具体IP(如192.168.128.2),可临时用该IP替代别名:PLAINTEXT://192.168.128.2:9092。若要适配容器动态IP,可通过TestContainers API获取:String kafkaBootstrap = kafka.getContainerIpAddress() + ":" + kafka.getMappedPort(9092);修改Kafka客户端DNS查找配置
Kafka客户端的client.dns.lookup参数默认值可能导致DNS解析逻辑异常,显式设置该参数为use_all_dns_ips,让客户端尝试解析所有返回的DNS IP:client.dns.lookup=use_all_dns_ips确认容器网络归属
确保被测应用容器与Kafka容器加入同一TestContainers网络,而非默认Docker bridge网络。统一网络配置示例:Network testNetwork = Network.newNetwork(); KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.0")) .withNetwork(testNetwork) .withNetworkAliases("kafka"); GenericContainer<?> appContainer = new GenericContainer<>(DockerImageName.parse("your-app-image")) .withNetwork(testNetwork);
后续注意事项
当前问题未涉及ADVERTISED_LISTENERS,但后续若连接成功后出现生产/消费失败,需检查Kafka容器的该配置,确保对外暴露的地址是被测应用可访问的容器别名或IP。
内容的提问来源于stack exchange,提问作者Matt Allwood

