【问题标题】:AWS Lambda Play Scala project with VPC throws UnknownHostException带有 VPC 的 AWS Lambda Play Scala 项目引发 UnknownHostException
【发布时间】:2016-07-18 11:01:36
【问题描述】:

我正在尝试根据示例 here 将 scala Play 应用程序作为 AWS Lambda 函数运行 该类是一个简单的函数:

 class PlayTask {

  // AWS Lambda Handler
  def exec(event: S3Event): String = WithApplication { App =>
    Play.current.configuration.getString("Play.Lambda.Greet").getOrElse("")
  }

  private def WithApplication[A](f: Application => A): A = {
    val env = Environment(new java.io.File("."), getClass.getClassLoader, Mode.Prod)
    val context = ApplicationLoader.createContext(env)
    val app = ApplicationLoader(context).load(context)
    try {
      Play.start(app)
      f(app)
    } finally {
      Play.stop(app)
    }
  }
}

jar 被加载到 S3 容器并连接到 VPC 以访问 RDS 和互联网。 但是,在连接 VPC 并运行 S3 put test 时,出现以下错误。

    at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:132) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:93) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:80) [task/:na] 
 at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:80) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:62) [task/:na] 
 at com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:984) [task/:na] 
 at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149) [task/:na] 
 at com.google.inject.util.Providers$GuicifiedProviderWithDependencies$$FastClassByGuice$$2a7177aa.invoke(<generated>) [task/:na] 
 at com.google.inject.internal.cglib.reflect.$FastMethod.invoke(FastMethod.java:53) [task/:na] 
 at com.google.inject.internal.SingleMethodInjector$1.invoke(SingleMethodInjector.java:57) [task/:na] 
 at com.google.inject.internal.SingleMethodInjector.inject(SingleMethodInjector.java:91) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:132) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:93) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:80) [task/:na] 
 at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) [task/:na] 
 at com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:80) [task/:na] 
 at com.google.inject.internal.Initializer$InjectableReference.get(Initializer.java:174) [task/:na] 
 at com.google.inject.internal.Initializer.injectAll(Initializer.java:108) [task/:na] 
 at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:174) [task/:na] 
 at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) [task/:na] 
 at com.google.inject.Guice.createInjector(Guice.java:96) [task/:na] 
 at com.google.inject.Guice.createInjector(Guice.java:73) [task/:na] 
 at com.google.inject.Guice.createInjector(Guice.java:62) [task/:na] 
 at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) [task/:na] 
 at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) [task/:na] 
 at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) [task/:na] 
 at example.PlayTask.WithApplication(PlayTask.scala:16) [task/:na] 
 at example.PlayTask.exec(PlayTask.scala:9) [task/:na] 
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_71] 
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_71] 
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_71] 
 at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_71] 
 at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.handleRequest(EventHandlerLoader.java:439) [lambda-sandbox.jar:na] 
 at lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:370) [lambda-sandbox.jar:na] 
 at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:972) [lambda-sandbox.jar:na] 
 at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:231) [lambda-sandbox.jar:na] 
 at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:59) [lambda-sandbox.jar:na] 
 at java.lang.Class.forName0(Native Method) [na:1.8.0_71] 
 at java.lang.Class.forName(Class.java:348) [na:1.8.0_71] 
 at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:93) [runtime/:na] 
Caused by: java.net.UnknownHostException: ip-10-0-77-249: unknown error 
 at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_71] 
 at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) ~[na:1.8.0_71] 
 at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) ~[na:1.8.0_71] 
 at java.net.InetAddress.getLocalHost(InetAddress.java:1500) ~[na:1.8.0_71]

我从 java.net.UnknownHostException 了解到该函数无法找到 localhost 的主机名并退回到本地环回。

【问题讨论】:

    标签: scala amazon-s3 playframework aws-lambda amazon-vpc


    【解决方案1】:

    jar 被加载到 S3 容器并连接到 VPC 以访问 RDS 和互联网。

    当您启用 VPC 访问时,您实际上禁用了对 VPC 外部任何内容的访问。您没有通过启用 VPC 为 Lambda 函数提供 Internet 访问权限,您实际上删除了 Internet 访问权限。此外,该函数不再有权访问 AWS API 服务器,这就是您在尝试访问 S3 时收到该错误的原因。您应该阅读this blog post announcing VPC support for Lambda 末尾的“须知”部分。

    如果您希望 Lambda 函数能够访问互联网和 AWS API 以及您的 VPC 之外的所有其他内容,那么您需要将 NAT Gateway 添加到您的 VPC。

    如果您只想将 S3 访问权限添加到您的 Lambda 函数,还有一个额外的选项是使用 S3 VPC Endpoint

    【讨论】:

    • 感谢您的评论。我已经通过将 NAT 网关添加到我的 VPC 来启用对 Internet 和 AWS API 的访问。确认配置正确的 AWS 支持人员证实了这一点。是否还有其他原因可能导致上述错误?
    【解决方案2】:

    似乎错误出在 AWS 方面。在昨天 AWS 对 Lambda 函数的停机之后,错误消失了。虽然我很好奇是什么原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-27
      • 2019-09-18
      • 2020-12-20
      • 2023-03-26
      • 2019-09-23
      • 2017-03-04
      • 2020-10-24
      相关资源
      最近更新 更多