Quarkus嵌入Hazelcast部署AWS ECS Fargate提示发现策略配置失败
问题描述
我尝试将搭载4.1版本嵌入式Hazelcast缓存的Quarkus 1.12.1.Final应用部署到AWS ECS Fargate,该嵌入式缓存在本地运行正常,但配置完成部署到AWS后报错Failed to configure discovery strategy。
完整错误栈
2021-09-28T10:51:19.518+02:00 Caused by: java.lang.RuntimeException: Failed to configure discovery strategies 2021-09-28T10:51:19.518+02:00 at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.loadDiscoveryStrategies(DefaultDiscoveryService.java:161) 2021-09-28T10:51:19.518+02:00 at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.<init>(DefaultDiscoveryService.java:58) 2021-09-28T10:51:19.519+02:00 at com.hazelcast.spi.discovery.impl.DefaultDiscoveryServiceProvider.newDiscoveryService(DefaultDiscoveryServiceProvider.java:29) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.Node.createDiscoveryService(Node.java:341) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.Node.<init>(Node.java:267) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.HazelcastInstanceImpl.createNode(HazelcastInstanceImpl.java:148) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.HazelcastInstanceImpl.<init>(HazelcastInstanceImpl.java:117) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.HazelcastInstanceFactory.constructHazelcastInstance(HazelcastInstanceFactory.java:211) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:190) 2021-09-28T10:51:19.520+02:00 at com.hazelcast.instance.impl.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:128) 2021-09-28T10:51:19.521+02:00 at com.hazelcast.core.Hazelcast.newHazelcastInstance(Hazelcast.java:57) 2021-09-28T10:51:19.521+02:00 at org.GreetingApplication.create(GreetingApplication.java:58) 2021-09-28T10:51:19.521+02:00 at org.GreetingApplication.init(GreetingApplication.java:32) 2021-09-28T10:51:19.521+02:00 at org.GreetingApplication_Bean.create(GreetingApplication_Bean.zig:700) 2021-09-28T10:51:19.521+02:00 at org.GreetingApplication_Bean.create(GreetingApplication_Bean.zig:716) 2021-09-28T10:51:19.521+02:00 at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96) 2021-09-28T10:51:19.521+02:00 at io.quarkus.arc.impl.AbstractSharedContext.access$000(AbstractSharedContext.java:14) 2021-09-28T10:51:19.521+02:00 at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29) 2021-09-28T10:51:19.522+02:00 at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26) 2021-09-28T10:51:19.522+02:00 at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26) 2021-09-28T10:51:19.522+02:00 at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69) 2021-09-28T10:51:19.522+02:00 at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26) 2021-09-28T10:51:19.522+02:00 at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:17) 2021-09-28T10:51:19.522+02:00 at org.GreetingApplication_ClientProxy.arc$delegate(GreetingApplication_ClientProxy.zig:67) 2021-09-28T10:51:19.522+02:00 at org.GreetingApplication_ClientProxy.arc_contextualInstance(GreetingApplication_ClientProxy.zig:82) 2021-09-28T10:51:19.523+02:00 at io.quarkus.arc.runtime.ClientProxyUnwrapper.apply(ClientProxyUnwrapper.java:11) 2021-09-28T10:51:19.523+02:00 at io.quarkus.resteasy.common.runtime.ResteasyInjectorFactoryRecorder$1.apply(ResteasyInjectorFactoryRecorder.java:22) 2021-09-28T10:51:19.523+02:00 at io.quarkus.resteasy.common.runtime.QuarkusInjectorFactory$UnwrappingPropertyInjector.inject(QuarkusInjectorFactory.java:65) 2021-09-28T10:51:19.523+02:00 at org.jboss.resteasy.core.ResteasyDeploymentImpl.createApplication(ResteasyDeploymentImpl.java:423) 2021-09-28T10:51:19.523+02:00 at org.jboss.resteasy.core.ResteasyDeploymentImpl.initializeObjects(ResteasyDeploymentImpl.java:266) 2021-09-28T10:51:19.523+02:00 at org.jboss.resteasy.core.ResteasyDeploymentImpl.startInternal(ResteasyDeploymentImpl.java:138) 2021-09-28T10:51:19.524+02:00 at org.jboss.resteasy.core.ResteasyDeploymentImpl.start(ResteasyDeploymentImpl.java:122) 2021-09-28T10:51:19.525+02:00 at io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder.staticInit(ResteasyStandaloneRecorder.java:35) 2021-09-28T10:51:19.525+02:00 at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy_0(ResteasyStandaloneBuildStep$staticInit-210558872.zig:906) 2021-09-28T10:51:19.525+02:00 at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy(ResteasyStandaloneBuildStep$staticInit-210558872.zig:40) 2021-09-28T10:51:19.525+02:00 at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:169) 2021-09-28T10:51:19.525+02:00 ... 9 more 2021-09-28T10:51:19.526+02:00 Caused by: com.hazelcast.aws.RestClientException: Failure in executing REST call 2021-09-28T10:51:19.526+02:00 at com.hazelcast.aws.RestClient.call(RestClient.java:114) 2021-09-28T10:51:19.526+02:00 at com.hazelcast.aws.RestClient.lambda$callWithRetries$0(RestClient.java:84) 2021-09-28T10:51:19.526+02:00 at com.hazelcast.aws.RetryUtils.retry(RetryUtils.java:50) 2021-09-28T10:51:19.526+02:00 at com.hazelcast.aws.RestClient.callWithRetries(RestClient.java:84) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.RestClient.get(RestClient.java:76) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.AwsMetadataApi.metadataEcs(AwsMetadataApi.java:92) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.AwsClientConfigurator.resolveCluster(AwsClientConfigurator.java:143) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.AwsClientConfigurator.createAwsClient(AwsClientConfigurator.java:65) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.AwsDiscoveryStrategy.<init>(AwsDiscoveryStrategy.java:79) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.aws.AwsDiscoveryStrategyFactory.newDiscoveryStrategy(AwsDiscoveryStrategyFactory.java:50) 2021-09-28T10:51:19.527+02:00 at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.buildDiscoveryStrategy(DefaultDiscoveryService.java:195) 2021-09-28T10:51:19.529+02:00 at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.loadDiscoveryStrategies(DefaultDiscoveryService.java:141) 2021-09-28T10:51:19.529+02:00 ... 44 more 2021-09-28T10:51:19.529+02:00 Caused by: java.net.SocketTimeoutException: Read timed out 2021-09-28T10:51:19.529+02:00 at java.base/java.net.SocketInputStream.socketRead0(Native Method) 2021-09-28T10:51:19.530+02:00 at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115) 2021-09-28T10:51:19.530+02:00 at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168) 2021-09-28T10:51:19.530+02:00 at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140) 2021-09-28T10:51:19.530+02:00 at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252) 2021-09-28T10:51:19.530+02:00 at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292) 2021-09-28T10:51:19.530+02:00 at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351) 2021-09-28T10:51:19.530+02:00 at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:754) 2021-09-28T10:51:19.530+02:00 at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:689) 2021-09-28T10:51:19.531+02:00 at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1615)
问题复现步骤
- 执行以下命令创建Quarkus样例项目:
mvn io.quarkus:quarkus-maven-plugin:1.11.7.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=getting-started -DclassName="org.acme.getting.started.GreetingResource" -Dpath="/hello"
- 新增Hazelcast依赖:
<dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-all</artifactId> <version>4.1</version> </dependency>
- 新增Application类初始化Hazelcast缓存,配置如下:
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false); config.getNetworkConfig().getJoin().getAwsConfig().setEnabled(true); config.getNetworkConfig().getInterfaces().setEnabled(true).addInterface("10.0.*.*");
解决方案
从错误栈可以判断,报错根因为Hazelcast访问ECS元数据接口超时,无法完成节点发现配置,可按以下顺序排查修复:
- 检查ECS任务执行角色权限:为任务附加包含
ecs:ListTasks、ecs:DescribeTasks、ec2:DescribeNetworkInterfaces权限的IAM策略,Hazelcast需要以上权限拉取同集群内其他实例的网络信息 - 核对网段配置:确认代码中配置的
10.0.*.*网段与Fargate任务所在VPC的子网网段完全匹配,如不匹配需要修改为实际VPC对应的网段范围 - 检查元数据接口连通性:Fargate默认开启ECS元数据端点v4,确认任务定义中没有关闭
ECS_ENABLE_CONTAINER_METADATA参数,同时任务绑定的安全组没有限制容器访问169.254.170.2元数据地址的出站请求 - 补充Hazelcast显式配置:在现有AWS配置基础上补充ECS集群名、区域、服务名配置,避免Hazelcast自动识别环境参数失败:
config.getNetworkConfig().getJoin().getAwsConfig() .setEnabled(true) .setProperty("cluster", "你的ECS集群名称") .setProperty("region", "你的AWS区域编码,如cn-north-1") .setProperty("service-name", "你的ECS服务名称");
- 调整依赖配置:替换
hazelcast-all全量包为独立的hazelcast和对应4.1版本的hazelcast-aws依赖,避免与Quarkus类加载机制产生包冲突 - 网络连通性验证:可在Fargate任务启动脚本中添加测试命令
curl http://169.254.170.2/v2/metadata,确认元数据接口可以正常返回结果后,再排查
相关产品推荐
相关产品推荐

