【问题标题】:[Amazon](500150) SocketTimeoutException. Works locally but not on Lambda [Redshift, Spring Data JDBC, Spring Boot][亚马逊](500150) SocketTimeoutException。在本地工作但不在 Lambda [Redshift、Spring Data JDBC、Spring Boot] 上工作
【发布时间】:2023-02-06 23:29:42
【问题描述】:

我正在开发一个简单的 API 来查询 Redshift,但我遇到的只是问题。目前的情况是,当我将它部署到 Lambda 时,我得到了一个 SocketTimeoutException。谷歌搜索此异常有大量建议添加"client CIDR/IP address to the VPC security group"。但是,我的凭据(和 IP)可以很好地让我从我的数据库客户端 (DBeaver) 访问 Redshift 数据库,以及当我在本地运行我的 Spring Boot 应用程序并从 Postman 调用它时。但是一旦它在 Lambda 上,我就会得到 SocketTimeoutException。

我正在联系团队以检查我是否确实需要将 IP 列入白名单,但在此之前我感到头疼的是 Spring Boot 构建时间太长导致其他类型的超时,我觉得这个问题有与 Spring Boot 的关系比与我的 Redshift 连接的关系更多。

我怀疑这一点的原因:

1.正如我所提到的,几天来我一直遇到超时问题,但是当我从建议的变体开始时它只切换到套接字超时:

public StreamLambdaHandler() throws ContainerInitializationException {
        long startTime = Instant.now().toEpochMilli();
        handler = new SpringBootProxyHandlerBuilder()
                .defaultProxy()
                .asyncInit(startTime)
                .springBootApplication(Application.class)
                .buildAndInitialize();
    }

我公司使用的不同 API 有哪些:

private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
        } catch (ContainerInitializationException e) {
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }

2个我的公司部署了一个更重的 api(有许多端点、服务类等),它只有 60kb,而我打包的单个端点 api 带有所有依赖项的阴影,这使它达到了惊人的 19.6MB!我猜这可能会影响加载时间?

3个本地加载需要 4.227 秒。 Full Stack Trace 真的很长,但这是我认为最相关的部分:

2023-02-06T07:13:30.139-06:00   INIT_START Runtime Version: java:11.v15 Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:blahhalb
2023-02-06T07:13:30.715-06:00   13:13:30.711 [main] INFO com.amazonaws.serverless.proxy.internal.LambdaContainerHandler - Starting Lambda Container Handler

*****Starts app at 7:13:31*****

2023-02-06T07:13:31.634-06:00   . ____ _ __ _ _
2023-02-06T07:13:31.634-06:00   /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2023-02-06T07:13:31.634-06:00   ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2023-02-06T07:13:31.634-06:00   \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2023-02-06T07:13:31.634-06:00   ' |____| .__|_| |_|_| |_\__, | / / / /
2023-02-06T07:13:31.634-06:00   =========|_|==============|___/=/_/_/_/
2023-02-06T07:13:31.638-06:00   :: Spring Boot ::
2023-02-06T07:13:31.834-06:00   2023-02-06 13:13:31.833 INFO 9 --- [ main] lambdainternal.AWSLambda : Starting AWSLambda using Java 11.0.14.1 on 169.254.10.245 with PID 9 (/var/runtime/lib/aws-lambda-java-runtime-0.2.0.jar started by sbx_user1051 in /var/task)
2023-02-06T07:13:31.835-06:00   2023-02-06 13:13:31.835 INFO 9 --- [ main] lambdainternal.AWSLambda : No active profile set, falling back to default profiles: default
2023-02-06T07:13:32.722-06:00   2023-02-06 13:13:32.722 INFO 9 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2023-02-06T07:13:32.787-06:00   2023-02-06 13:13:32.787 INFO 9 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 58 ms. Found 1 JDBC repository interfaces.
2023-02-06T07:13:33.194-06:00   2023-02-06 13:13:33.194 INFO 9 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring embedded WebApplicationContext
2023-02-06T07:13:33.194-06:00   2023-02-06 13:13:33.194 INFO 9 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1281 ms
2023-02-06T07:13:33.587-06:00   2023-02-06 13:13:33.585 INFO 9 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2023-02-06T07:13:40.762-06:00   13:13:40.758 [main] INFO 

***** After failing to make connection after 7 seconds, restarts app*****

com.amazonaws.serverless.proxy.internal.LambdaContainerHandler - Starting Lambda Container Handler
2023-02-06T07:13:41.613-06:00   . ____ _ __ _ _
2023-02-06T07:13:41.613-06:00   /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2023-02-06T07:13:41.613-06:00   ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2023-02-06T07:13:41.613-06:00   \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2023-02-06T07:13:41.613-06:00   ' |____| .__|_| |_|_| |_\__, | / / / /
2023-02-06T07:13:41.613-06:00   =========|_|==============|___/=/_/_/_/
2023-02-06T07:13:41.616-06:00   :: Spring Boot ::
2023-02-06T07:13:41.807-06:00   2023-02-06 13:13:41.805 INFO 12 --- [ main] lambdainternal.AWSLambda : Starting AWSLambda using Java 11.0.14.1 on 169.254.10.245 with PID 12 (/var/runtime/lib/aws-lambda-java-runtime-0.2.0.jar started by sbx_user1051 in /var/task)
2023-02-06T07:13:41.807-06:00   2023-02-06 13:13:41.807 INFO 12 --- [ main] lambdainternal.AWSLambda : No active profile set, falling back to default profiles: default
2023-02-06T07:13:42.699-06:00   2023-02-06 13:13:42.699 INFO 12 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2023-02-06T07:13:42.762-06:00   2023-02-06 13:13:42.761 INFO 12 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 56 ms. Found 1 JDBC repository interfaces.
2023-02-06T07:13:43.160-06:00   2023-02-06 13:13:43.160 INFO 12 --- [ main] c.a.s.p.i.servlet.AwsServletContext : Initializing Spring embedded WebApplicationContext
2023-02-06T07:13:43.160-06:00   2023-02-06 13:13:43.160 INFO 12 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1277 ms
2023-02-06T07:13:43.549-06:00   2023-02-06 13:13:43.548 INFO 12 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2023-02-06T07:14:14.685-06:00   2023-02-06 13:14:14.684 ERROR 12 --- [ main] 

*****Tries to make a connection for 31 seconds before giving me the SocketTimeoutException*****

com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
2023-02-06T07:14:14.685-06:00   java.sql.SQLException: [Amazon](500150) Error setting/closing connection: SocketTimeoutException.
2023-02-06T07:14:14.685-06:00   at com.amazon.redshift.client.PGClient.connect(Unknown Source) ~[task/:na]
2023-02-06T07:14:14.685-06:00   at com.amazon.redshift.client.PGClient.<init>(Unknown Source) ~[task/:na]
2023-02-06T07:14:14.685-06:00   at com.amazon.redshift.core.PGJDBCConnection.connect(Unknown Source) ~[task/:na]
2023-02-06T07:14:14.685-06:00   at com.amazon.jdbc.common.BaseConnectionFactory.doConnect(Unknown Source) ~[task/:na]
2023-02-06T07:14:14.685-06:00   at com.amazon.jdbc.common.AbstractDriver.connect(Unknown Source) ~[task/:na]
2023-02-06T07:14:14.685-06:00   at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[task/:na]

难不成这是Spring Boot构建超时异常?还是更有可能是 Redshift 连接问题?

【问题讨论】:

    标签: amazon-web-services spring-boot aws-lambda amazon-redshift hikaricp


    【解决方案1】:

    所以你的用例是编写一个 AWS Lambda 函数,可以在 Redshift 集群上执行 CRUD 操作?如果是这样,您可以使用 Java Lambda 运行时 API 来实现此用例。

    com.amazonaws.services.lambda.runtime.RequestHandler

    要从 Lambda 执行 Redshift 数据 CRUD 操作,您可以使用 software.amazon.awssdk.services.redshiftdata.RedshiftDataClient

    正确设置 Lambda 函数后,您可以使用 Redshift 数据客户端修改数据。例如:

    private RedshiftDataClient getClient() {
    
            Region region = Region.US_WEST_2;
            RedshiftDataClient redshiftDataClient = RedshiftDataClient.builder()
                    .region(region)
                    .build();
    
            return redshiftDataClient;
         }
    
        public void delPost(String id) {
    
            try {
    
                RedshiftDataClient redshiftDataClient = getClient();
                String sqlStatement = "DELETE FROM blog WHERE idblog = '" + id + "'";
    
                ExecuteStatementRequest statementRequest = ExecuteStatementRequest.builder()
                        .clusterIdentifier(clusterId)
                        .database(database)
                        .dbUser(dbUser)
                        .sql(sqlStatement)
                        .build();
    
                redshiftDataClient.executeStatement(statementRequest);
    
            } catch (RedshiftDataException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }
          } 
    

    此外 - 当您的 Lambda 函数调用 Amazon Redshift 时,Lambda 函数使用的 IAM 角色必须有一个策略,使其能够从 Lambda 函数调用此 AWS 服务。

    总之,您可以使用 RedshiftDataClient 而不是 Spring API 从 AWS Lambda 函数插入/修改/删除 Redshift 数据。

    【讨论】:

      猜你喜欢
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 2016-10-04
      • 2015-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多