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.
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 |
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.
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