Estoy usando el marco de trabajo sin servidor (serverless.com) y parece que puedo ahorrar bastante dinero aumentando solo la capacidad aprovisionada de mis funciones de Lambda durante el horario laboral (de 9 a. m. a 5 p. m., 40 horas por semana) y luego reduciéndola a cero durante las horas de descanso. Mi aplicación no se usa mucho fuera del horario laboral, y si lo es, mis usuarios están de acuerdo con los arranques en frío y que tarden más.
En mi serverless.yml, tengo funciones declaradas como:
home_page: handler: homePage/home_page_handler.get events: - http: path: homePage method: get cors: true authorizer: authorizer_handler provisionedConcurrency: 1También tengo un Lambda que se ejecuta regularmente para configurar la capacidad aprovisionada de los otros Lambda en la cuenta según la hora del día. En esa lambda si llamo:
await lambda.putProvisionedConcurrencyConfig({ FunctionName: myFunctionName, ProvisionedConcurrentExecutions: 0, Qualifier: "provisioned", }).promise();Entonces me sale este error:
Received error: ValidationException: 1 validation error detected: Value '0' at 'provisionedConcurrentExecutions' failed to satisfy constraint: Member must have value greater than or equal to 1 at Object.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27) at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/rest_json.js:55:8) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9) at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12) { code: 'ValidationException', time: 2021-08-14T17:45:48.932Z, requestId: '8594fad6-d5dd-4a00-adca-c34f9d38b25e', statusCode: 400, retryable: false, retryDelay: 77.81562781029108 }Por otro lado, si trato de eliminar la capacidad aprovisionada por completo, así:
await lambda.deleteProvisionedConcurrencyConfig({ FunctionName: myFunctionName, Qualifier: "provisioned", }).promise();Eso funciona bien, pero cuando trato de implementar mi función nuevamente fuera del horario laboral (que es la norma), CloudFormation falla con:
No Provisioned Concurrency Config found for this function (Service: AWSLambdaInternal; Status Code: 404; Error Code: ProvisionedConcurrencyConfigNotFoundException; Request ID: 75dd221b-35d2-4a49-80c5-f07ce261d357; Proxy: null)¿Alguien tiene una solución ordenada para desactivar la capacidad aprovisionada durante algunas horas del día?
Después de pensarlo un poco, si todavía está comprometido con Lambda como la solución informática, creo que su mejor opción es administrar la concurrencia aprovisionada fuera de Serverless Framework por completo.
Ya tiene una función de orquestador que habilitará la simultaneidad aprovisionada, podría intentar eliminar provisionedConcurrency de su archivo serverless.yml , agregar otro método en su orquestador para deshabilitar la moneda aprovisionada por las noches y verificar que puede implementar cuando su orquestador tiene establezca sus funciones en cualquier estado.
Si está dispuesto a deshacerse de su función de orquestador, AWS sugiere usar Application Auto Scaling , que es muy útil exactamente para lo que está haciendo. (punta de sombrero para @mpv)
Dicho esto, Lambda no se adapta particularmente bien al tráfico predecible y de estado estable. Si el costo es una preocupación, sugeriría explorar Fargate o ECS y escribir algunas reglas de escalado automático. Su código Lambda ya no tiene estado, y probablemente sea portátil y tenga reglas de red bastante limitadas. Hay otras formas de cómputo que serían dramáticamente más baratas de usar.