多次创建JClouds ComputeService到AWS会引发“自定义提供程序错误”异常

时间:2012-08-24 12:28:10

标签: amazon-web-services jclouds

我正在开发一个系统,它可以利用jclouds来实例化亚马逊云上的一堆节点。

当我需要知道我已经创建的节点时,我使用了computeService.listNodes()。 对于listNodes的每次调用,我创建一个对象computeService,如下所示:

Properties overrides = new Properties();
overrides.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "image-id=" + image);

ComputeServiceContext context = new ComputeServiceContextFactory()
.createContext(PROVIDER,
  Configuration.get("AMAZON_ACCESS_KEY_ID"),
  Configuration.get("AMAZON_SECRET_KEY"),
  ImmutableSet.<Module> of(), overrides);

computeService = context.getComputeService();

通常它可以工作,但是当我对computeService.listNodes()进行多次并发调用时,执行失败。

在这样的执行中,我在createContext行的某些线程中得​​到了异常。附加了完整的堆栈跟踪。

让我感到困惑的是,我编写了一个带循环的小程序来实例化多个computeServices,我没有遇到任何麻烦。

我是否会使用JClouds API进行错误的使用? JClouds不支持并发调用吗?或者它会对AWS调用有某种限制吗? (上一段表明这些问题的答案是“不”,但我现在无法考虑其他选项。)

重要信息:我的代码从REST调用运行到使用apache cxf设置的独立本地服务器。

这是负责设置服务器的类:https://github.com/choreos/choreos_middleware/blob/master/ServiceDeployer/src/main/java/org/ow2/choreos/npm/rest/NPMServer.java

这是接收调用的类:https://github.com/choreos/choreos_middleware/blob/master/ServiceDeployer/src/main/java/org/ow2/choreos/npm/rest/NodesResource.java

堆栈跟踪的一些相关部分:

1) Error in custom provider, java.lang.reflect.UndeclaredThrowableException
  while locating org.jclouds.ec2.config.EC2RestClientModule$RegionIdToZoneId
    Caused by: java.lang.reflect.UndeclaredThrowableException
    at $Proxy98.describeAvailabilityZonesInRegion(Unknown Source)
    at     org.jclouds.ec2.config.EC2RestClientModule$RegionIdToZoneId.get(EC2RestClientModule.java:152)
Caused by: java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:258)
at java.util.concurrent.FutureTask.get(FutureTask.java:119)
at     org.jclouds.concurrent.config.ExecutorServiceModule$AddToStringFuture.get(ExecutorServiceModule.java:234)

2) Error in custom provider, org.jclouds.http.HttpResponseException: ec2.ap-northeast-1.amazonaws.com connecting to POST https://ec2.ap-northeast-1.amazonaws.com/ HTTP/1.1
  while locating org.jclouds.ec2.config.EC2RestClientModule$RegionIdToZoneId
Caused by: org.jclouds.http.HttpResponseException: ec2.ap-northeast-1.amazonaws.com connecting to POST https://ec2.ap-northeast-1.amazonaws.com/ HTTP/1.1
at     org.jclouds.http.internal.BaseHttpCommandExecutorService$HttpResponseCallable.call(BaseHttpCommandExecutorService.java:183)
Caused by: java.net.UnknownHostException: ec2.ap-northeast-1.amazonaws.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:175)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)

OBS:堆栈跟踪中的“at org.ow2.choreos.npm.cloudprovider.AWSCloudProvider.getClient(AWSCloudProvider.java:53)”行是“createContext”行。

谢谢你, 莱昂纳多雷特

1 个答案:

答案 0 :(得分:1)

jclouds中的节点查询未缓存,因此多个并发请求可能导致网络超时。 如果您同时执行多个listNodes,则可以考虑使用guava cache

无论如何,我会碰到jclouds 1.5.3,它也有更清晰的语法来创建连接。

ComputeServiceContext context = ContextBuilder.newBuilder(PROVIDER)
                                              .credentials(Configuration.get("AMAZON_ACCESS_KEY_ID"), Configuration.get("AMAZON_SECRET_KEY"))
                                              .overrides(properties)
                                              .buildView(ComputeServiceContext.class);

最后,您可以通过提供上下文属性“jclouds.regions”以及您感兴趣的区域的逗号分隔列表来隔离您使用的区域。例如“us-west-1”将阻止网络调用到偏远地区。