Suporte ao Rust para instâncias gerenciadas do Lambda - AWS Lambda

Suporte ao Rust para instâncias gerenciadas do Lambda

Configuração de simultaneidade

O número máximo de solicitações simultâneas que o Lambda envia para cada ambiente de execução é controlado pela definição PerExecutionEnvironmentMaxConcurrency da configuração da função. Esta é uma configuração opcional, e o valor padrão no Rust é de 8 solicitações simultâneas por vCPU; você também pode definir seu próprio valor. Esse valor determina o número de tarefas da Tokio criadas pelo runtime e permanece fixo durante todo o tempo de vida do ambiente de execução. Cada operador lida com exatamente uma solicitação em andamento por vez, sem multiplexação por operador. O Lambda ajusta automaticamente o número de solicitações simultâneas até o máximo configurado com base na capacidade de cada ambiente de execução de absorver essas solicitações.

Funções de construção para multissimultaneidade

É necessário aplicar as mesmas práticas de segurança de thread ao usar instâncias gerenciadas do Lambda como você faria em qualquer outro ambiente de vários threads. Como o objeto manipulador é compartilhado entre todas as threads de operador, qualquer estado mutável deve ser seguro para threads. Isso inclui coleções, conexões de banco de dados e quaisquer objetos estáticos que sejam modificados durante o processamento da solicitação.

Para habilitar o tratamento simultâneo de solicitações, adicione o sinalizador de recurso concurrency-tokio ao arquivo Cargo.toml.

[dependencies] lambda_runtime = { version = "1", features = ["concurrency-tokio"] }

O ponto de entrada lambda_runtime::run_concurrent(…) deve ser chamado de dentro de um runtime da Tokio, normalmente fornecido pelo atributo #[tokio::main] em sua função principal. O fechamento do manipulador deve implementar Clone + Send. Isso permite que o framework compartilhe seu manipulador entre várias tarefas assíncronas com segurança. Se esses limites não forem respeitados, seu código não será compilado.

Quando você precisar de um estado compartilhado entre invocações (um pool de bancos de dados, uma estrutura de configuração), envolva-o em Arc e clone Arc em cadainvocação.

Todos os clientes do AWS SDK para Rust são seguros contra concorrência e não exigem tratamento especial.

Exemplo: cliente do AWS SDK

O exemplo abaixo usa um cliente do S3 para carregar um objeto em cada invocação. O cliente é clonado diretamente no fechamento sem Arc:

let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let s3_client = aws_sdk_s3::Client::new(&config); run_concurrent(service_fn(move |event: LambdaEvent<Request>| { let s3_client = s3_client.clone(); // cheap clone, no Arc needed async move { s3_client.put_object() .bucket(&event.payload.bucket) .key(&event.payload.key) .body(event.payload.body.into_bytes().into()) .send() .await?; Ok(Response { message: "uploaded".into() }) } })) .await

Exemplo: grupos de conexão de banco de dados

Quando o manipulador precisar acessar um estado compartilhado, como um cliente e uma configuração, envolva-o em Arc e clone Arc em cada invocação:

#[derive(Debug)] struct AppState { dynamodb_client: DynamoDbClient, table_name: String, cache_ttl: Duration, } let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let state = Arc::new(AppState { dynamodb_client: DynamoDbClient::new(&config), table_name: std::env::var("TABLE_NAME").expect("TABLE_NAME must be set"), cache_ttl: Duration::from_secs(300), }); run_concurrent(service_fn(move |event: LambdaEvent<Request>| { let state = state.clone(); async move { handle(event, state).await } })) .await

Diretório /tmp compartilhado

O diretório /tmp é compartilhado entre todas as chamadas simultâneas no mesmo ambiente de execução. Use nomes de arquivo exclusivos para cada chamada (por exemplo, inclua o ID da solicitação) ou implemente o bloqueio explícito de arquivos para evitar corrupção de dados.

Registro em log

A intercalação de logs (entradas de logs de solicitações diferentes sendo intercaladas em logs) é normal em sistemas multissimultâneos. Funções do Lambda que utilizam Instâncias gerenciadas do Lambda oferecem suporte ao formato de log JSON estruturado por meio de controles avançados de registro de logs do Lambda. Esse formato inclui o requestId, permitindo que as entradas de log sejam correlacionadas a uma única solicitação. Consulte para obter mais informações Implementar registro em log avançado com a caixa Tracing.

Contexto da solicitação

O objeto Context é passado diretamente para cada invocação do manipulador. Use event.context.request_id para acessar o ID para a solicitação atual.

Use event.context.xray_trace_id para acessar o ID de rastreamento do X-Ray. O Lambda não oferece suporte à variável de ambiente _X_AMZN_TRACE_ID com instâncias gerenciadas do Lambda. O ID de rastreamento do X-Ray é propagado automaticamente ao usar o AWS SDK para Rust.

Use event.context.deadline para detectar tempos limite: ele contém o prazo de invocação em milissegundos.

Inicialização e desligamento

A inicialização da função ocorre uma vez por ambiente de execução. Os objetos criados durante a inicialização são compartilhados entre as solicitações.

Para as funções do Lambda com extensões, o ambiente de execução emite um sinal SIGTERM durante o desligamento. Esse sinal é usado por extensões como um gatilho para tarefas de limpeza, como a liberação de buffers. lambda_runtime oferece uma função auxiliar para simplificar a configuração do tratamento de sinais de desligamento ordenado, spawn_graceful_shutdown_handler(). Para saber mais sobre o ciclo de vida do ambiente de execução, consulte Noções básicas sobre o ciclo de vida do ambiente de execução do Lambda.

Versões de dependências

As instâncias gerenciadas do Lambda exigem as versões mínimas de pacotes a seguir:

  • lambda_runtime: versão 1.1.1 ou posterior, com o recurso concurrency-tokio habilitado

  • A versão mínima compatível do Rust (MSRV) é a 1.84.0.