LocalStack+Testcontainers中Lambda无法连接Redis测试容器问题
问题:LocalStack+Testcontainers集成Lambda测试中Redis连接失败
我正在为接收KinesisEvent触发、并向Redis和Kafka写入数据的AWS Lambda函数编写集成测试,采用LocalStack与Testcontainers实现。通过docker-compose.yml测试代码可正常运行,但Java测试中出现异常。
容器配置代码
@ClassRule public static final LocalStackContainer localstack = new LocalStackContainer(localstackImage) .withEnv("AWS_DEFAULT_REGION", US_EAST_1.getName()) .withNetwork(lambdaNetwork) .withServices(Service.KINESIS, Service.LAMBDA); @ClassRule public static final KafkaContainer kafkaContainer = new KafkaContainer(kafkaImage).withNetwork(lambdaNetwork).withExposedPorts(9093); redisContainer = new GenericContainer<>(redisImage).withNetwork(lambdaNetwork).withExposedPorts(6379); redisContainer.start(); String redisHost = redisContainer.getHost(); Integer redisPort = redisContainer.getFirstMappedPort();
触发Lambda时的异常
2023-08-24T18:41:03.309 WARN --- [ asgi_gw_1] l.s.a.i.executor_endpoint : Execution environment startup failed: {"errorMessage":"Failed to connect to any host resolved for DNS name.","errorType":"redis.clients.jedis.exceptions.JedisConnectionException"}
已为容器配置网络,请问可能遗漏了什么配置?
解决方案
核心问题:容器间网络访问方式错误
你当前获取的redisContainer.getHost()和getFirstMappedPort()是宿主机的端口映射信息,但LocalStack内部运行的Lambda容器处于lambdaNetwork这个Docker网络中,无法直接通过宿主机端口访问Redis容器。同一Docker网络内的容器,必须使用容器网络别名作为主机名、容器原生内部端口通信,而非宿主机映射端口。
具体修复步骤
为Redis容器设置固定网络别名
创建Redis容器时添加withNetworkAliases,指定网络内可解析的固定名称:redisContainer = new GenericContainer<>(redisImage) .withNetwork(lambdaNetwork) .withExposedPorts(6379) .withNetworkAliases("redis"); // 设置网络内可识别的别名修改Lambda的Redis连接配置
Lambda代码中连接Redis的参数需调整为:- 主机名:
redis(上述设置的网络别名) - 端口:
6379(Redis容器的原生内部端口,无需使用宿主机映射端口)
- 主机名:
验证网络连通性(可选)
进入LocalStack容器内部,执行ping redis或telnet redis 6379,确认名称解析与端口连通性正常。
补充说明
docker-compose能正常运行的原因是:它默认会为每个服务创建以服务名为名称的网络别名,容器间可直接通过服务名访问;而Testcontainers若不手动设置withNetworkAliases,容器名称是随机生成的,无法被Lambda容器解析到。
内容的提问来源于stack exchange,提问作者SWA PSTG
相关产品推荐
相关产品推荐

