"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Aplicación Spring Boot en AWS Lambda: parte Medición de arranques en frío y en caliente con la función Spring Cloud

Aplicación Spring Boot en AWS Lambda: parte Medición de arranques en frío y en caliente con la función Spring Cloud

Publicado el 2024-08-19
Navegar:190

Spring Boot pplication on AWS Lambda - Part Measuring cold and warm starts with Spring Cloud Function

Introducción

En la parte 8 presentamos el concepto detrás de la función Spring Cloud y en la parte 9 demostramos cómo desarrollar AWS Lambda con la función Spring Cloud usando Java 21 y Spring Boot 3.2. En este artículo de la serie, mediremos el tiempo de inicio en frío y en caliente, incluida la habilitación de SnapStart en la función Lambda, pero también aplicaremos varias técnicas de preparación, como preparar la invocación de DynamoDB y preparar (proxy) toda la solicitud de API Gateway sin pasar por la red. . Usaremos la aplicación de muestra Spring Boot 3.2 para nuestras mediciones, y para todas las funciones Lambda usaremos JAVA_TOOL_OPTIONS: "-XX: TieredCompilation -XX:TieredStopAtLevel=1" y les daremos Lambda 1024 MB de memoria.

Medición de arranques en frío y tiempo de calentamiento con Spring Cloud Function y usando Java 21 y Spring Boot 3.2

Comencemos explicando cómo habilitar AWS SnapStart en la función Lambda, ya que (con el cebado en la parte superior) proporciona el mayor potencial de optimización del rendimiento de Lambda (especialmente los tiempos de inicio en frío). Es sólo una cuestión de configuración:

SnapStart:
  ApplyOn: PublishedVersions 

aplicado en las propiedades de la función Lambda o en la sección de función global de la plantilla SAM. Me gustaría profundizar más sobre cómo utilizar varias técnicas de preparación además de SnpaStart para nuestro caso de uso. Expliqué las ideas detrás del cebado en mi artículo AWS Lambda SnapStart: medición del cebado, la latencia de extremo a extremo y el tiempo de implementación

1) El código para preparar la solicitud de DynamoDB se puede encontrar aquí.

Esta clase implementa adicionalmente import org.crac.Interfaz de recursos del proyecto CraC.

Con esta invocación

Core.getGlobalContext().register(this);

La clase GetProductByIdWithDynamoDBRequestPrimingHandler se registra como recurso CRaC.

Además, preparamos la invocación de DynamoDB implementando el método beforeCheckpoint desde la API CRaC.

      @Override
      public void beforeCheckpoint(org.crac.Context extends Resource> context) throws Exception {
             productDao.getProduct("0");
      }

que invocaremos durante la fase de implementación de la función Lambda y antes de que se tome la instantánea de Firecracker microVM.

2) El código para preparar toda la solicitud de API Gateway se puede encontrar aquí.

Esta clase también implementa adicionalmente la interfaz import org.crac.Resource como en el ejemplo anterior.
Reutilizaremos la técnica fea, que describí en mi artículo AWS Lambda SnapStart: Parte 6 Preparación de la invocación de solicitud para los marcos Java 11 y Micronaut, Quarkus y Spring Boot. No recomiendo usar esta técnica en producción, pero demuestra los potenciales adicionales para reducir el arranque en frío mediante el cebado de toda la solicitud de API Gateway mediante la precarga del mapeo entre los modelos Spring Boot y Spring Cloud Function y el modelo Lambda que también realiza DynamoDB. preparación de invocación.

La construcción de la solicitud API Gateway de /products/{id} con id igual a 0 La solicitud JSON de API Gateway tiene este aspecto:

      private static String getAPIGatewayRequestMultiLine () {
             return  """
                        {
                      "resource": "/products/{id}",
                      "path":  "/products/0",
                      "httpMethod": "GET",
                      "pathParameters": {
                            "id": "0" 
                        },
                       "requestContext": {
                          "identity": {
                        "apiKey": "blabla"
                      }
                      }
                    }
           """;
      }

El beforeCheckpoint cuando prepara (representa) toda la solicitud de API Gateway sin pasar por la red usando la clase Spring Cloud Function FunctionInvoker que invoca su método handleRequest pasando el flujo de entrada de la API Solicitud JSON de puerta de enlace construida arriba de esta manera:

@Override
public void beforeCheckpoint(org.crac.Context extends Resource> context) throws Exception {
            
new FunctionInvoker().handleRequest( 
  new ByteArrayInputStream(getAPIGatewayRequestMultiLine().
  getBytes(StandardCharsets.UTF_8)),
  new ByteArrayOutputStream(), new MockLambdaContext());
}

Los resultados del siguiente experimento se basaron en la reproducción de más de 100 arranques en frío y aproximadamente 100.000 arranques en caliente con la función Lambda con una configuración de memoria de 1024 MB durante 1 hora. Para ello utilicé la herramienta de prueba de carga, pero puedes usar la herramienta que quieras, como Serverless-artillery o Postman.

Hice todos estos experimentos con 4 escenarios diferentes:

1) No hay SnapStart habilitado

En template.yaml use la siguiente configuración:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest    
      #SnapStart:
         #ApplyOn: PublishedVersions      

y necesitamos invocar la función Lambda con el nombre GetProductByIdWithSpringBoot32SCF que está asignada a la clase Java GetProductByIdHandler Lambda Handler.

2) SnapStart habilitado pero sin cebado aplicado

En template.yaml use la siguiente configuración:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest 
    SnapStart:
      ApplyOn: PublishedVersions 

y necesitamos invocar la misma función Lambda con el nombre GetProductByIdWithSpringBoot32SCF que está asignada a la clase Java GetProductByIdHandler Lambda Handler.
3) SnapStart habilitado con preparación de invocación de DynamoDB

En template.yaml use la siguiente configuración:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest    
    SnapStart:
      ApplyOn: PublishedVersions      

y necesitamos invocar la función Lambda con el nombre GetProductByIdWithSpringBoot32SCFAndDynamoDBRequestPriming que está asignada a la clase Java GetProductByIdWithDynamoDBRequestPrimingHandler Lambda Handler.

4) SnapStart habilitado con preparación/proxy de invocación de solicitud de API Gateway

En template.yaml use la siguiente configuración:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
    SnapStart:
      ApplyOn: PublishedVersions      

y necesitamos invocar la función Lambda con nombre
GetProductByIdWithSpringBoot32SCFAndWebRequestPriming que está asignado a la clase Java GetProductByIdWithWebRequestPrimingHandler Lambda Handler.

Abreviatura c es para arranque en frío y w es para arranque en caliente.

Hora de inicio en frío (c) y caliente (w) en ms:

Número de escenario cp50 c p75 c p90 c p99 c p99.9 c máx w p50 w p75 w p90 w p99 w p99.9 w máx
No hay SnapStart habilitado 4768.34 4850.11 4967.86 5248.61 5811.92 5813.31 7.16 8.13 9.53 21.75 62.00 1367.52
SnapStart habilitado pero sin cebado aplicado 2006.60 2065.61 2180.17 2604.69 2662.60 2663.54 7.45 8.40 9.92 23.09 1354.50 1496.46
SnapStart habilitado con preparación de invocación de DynamoDB 1181.40 1263.23 1384,90 1533.54 1661.20 1662.17 7.57 8.73 10.83 23.83 492.37 646.18
SnapStart habilitado con preparación de invocación de solicitud de API Gateway 855.45 953.91 1107.10 1339,97 1354,78 1355.21 8.00 9.53 12.09 26.31 163,26 547.28

Conclusión

Al habilitar SnapStart solo en la función Lambda, se reduce significativamente el tiempo de inicio en frío de la función Lambda. Al utilizar adicionalmente el cebado de invocación de DynamoDB, podemos lograr arranques en frío solo ligeramente superiores a los arranques en frío descritos en mi artículo AWS SnapStart: medición de arranques en frío y en caliente con Java 21 utilizando diferentes configuraciones de memoria donde medimos los arranques en frío y en caliente para Lambda puro. funcionar sin el uso de ningún marco, incluida la configuración de memoria de 1024 MB, como en nuestro escenario.

Al comparar los tiempos de inicio en frío y en caliente que medimos con AWS Serverless Java Container en el artículo Medición de inicios en frío y en caliente con AWS Serverless Java Container y Medición de inicios en frío y en caliente con AWS Lambda Web Adapter, observamos que Spring Cloud Function ofrece un mayor frío tiempos de inicio que AWS Lambda Web Adaptor, pero tiempos de inicio en frío bastante comparables a los de AWS Serverless Java Container (los resultados varían ligeramente según los percentiles). En términos de tiempos de arranque/ejecución en caliente, los 3 enfoques tienen resultados bastante comparables cuando se analizan especialmente los percentiles por debajo de 99,9.

Declaración de liberación Este artículo se reproduce en: https://dev.to/aws-builders/spring-boot-3-application-on-aws-lambda-part-10-measuring-cold-and-warm-starts-with-spring- cloud- function-2b1i?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3