【问题标题】:spring boot cold start taking too long on aws lambda and boot initializes twicespring boot 冷启动在 aws lambda 上花费的时间太长,并且 boot 初始化两次
【发布时间】:2020-12-24 08:11:47
【问题描述】:

这很奇怪,但我的 spring boot api 在 aws lambda 上部署时花费的时间比预期的要长得多。 在 cloudwatch 日志中,我看到 spring boot 启动了两次,第一次使用默认配置文件,第二次使用我设置的配置文件。 为什么要启动两次..这会花费大量时间.. 源代码: lambdahandler.java

public class LambdaHandler implements RequestStreamHandler {

    private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;

    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
            handler.activateSpringProfiles("lambda");
        } catch (ContainerInitializationException e) {
            // Re-throw the exception to force another cold start
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }

application.java

@SpringBootApplication
    public class Application extends SpringBootServletInitializer {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }

这两个文件在同一个包中

config.java

@Configuration
@EnableWebMvc
@Profile("lambda")
public class Config {

    /**
     * Create required HandlerMapping, to avoid several default HandlerMapping instances being created
     */
    @Bean
    public HandlerMapping handlerMapping() {
        return new RequestMappingHandlerMapping();
    }

    /**
     * Create required HandlerAdapter, to avoid several default HandlerAdapter instances being created
     */
    @Bean
    public HandlerAdapter handlerAdapter() {
        return new RequestMappingHandlerAdapter();
    }
..
..

}

pom.xml

<dependency>
      <groupId>com.amazonaws.serverless</groupId>
      <artifactId>aws-serverless-java-container-spring</artifactId>
      <version>[0.1,)</version>
    </dependency>
<dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-core</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-events</artifactId>
      <version>3.1.0</version>
    </dependency>

cloudwatch 日志

    07:16:51.546 [main] INFO com.amazonaws.serverless.proxy.internal.LambdaContainerHandler - Starting Lambda Container Handler
:: Spring Boot ::                        
    2020-09-05 07:16:52.724  INFO 1 --- [           main] lambdainternal.LambdaRTEntry             : Starting LambdaRTEntry on 169.254.184.173 with PID 1 (/var/runtime/lib/LambdaJavaRTEntry-1.0.jar started by sbx_user1051 in /)
    2020-09-05 07:16:52.726  INFO 1 --- [           main] lambdainternal.LambdaRTEntry             : No active profile set, falling back to default profiles: default
    2020-09-05 07:16:52.906  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1e81f4dc: startup date [Sat Sep 05 07:16:52 UTC 2020]; root of context hierarchy
    
    ..
    ..
    2020-09-05 07:16:57.222  INFO 1 --- [           main] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 40 ms
    :: Spring Boot ::                        
    2020-09-05 07:16:57.442  INFO 1 --- [           main] lambdainternal.LambdaRTEntry             : Starting LambdaRTEntry on 169.254.184.173 with PID 1 (/var/runtime/lib/LambdaJavaRTEntry-1.0.jar started by sbx_user1051 in /)
    2020-09-05 07:16:57.442  INFO 1 --- [           main] lambdainternal.LambdaRTEntry             : The following profiles are active: lambda
    2020-09-05 07:16:57.445  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5ef60048: startup date [Sat Sep 05 07:16:57 UTC 2020]; root of context hierarchy

【问题讨论】:

    标签: java spring-boot aws-lambda aws-serverless cold-start


    【解决方案1】:

    为什么要开机两次?

    我怀疑您的代码更改为 activateSpringProfiles 强制重新初始化。

    handler.activateSpringProfiles("lambda");
    

    https://github.com/awslabs/aws-serverless-java-container/blob/master/aws-serverless-java-container-spring/src/main/java/com/amazonaws/serverless/proxy/spring/SpringBootLambdaContainerHandler.java#L149

    尝试使用环境变量 SPRING_PROFILES_ACTIVE 设置活动配置文件作为 lambda 配置文件的一部分。

    Java 和无服务器

    如果您将 java 用于 AWS lambda 等无服务器应用程序,我建议您寻找一个支持 Ahead-of-Time 编译的框架,这将大大促进您的应用程序启动。

    例如,看看使用 Graalvm 的 Micronaut、Quarkus。 Spring Boot 不是直接与 AWS lambda 一起使用的最佳选择。

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 2022-11-30
      相关资源
      最近更新 更多