Docs Menu
Docs Home
/

Administra conexiones con AWS Lambda

Utilice las siguientes prácticas recomendadas para administrar adecuadamente las conexiones entre AWS Lambda y Atlas:

  • Define el cliente para el servidor MongoDB fuera de la función del controlador de AWS Lambda.

    No definas una nueva MongoClient objeto cada vez que invoca su función. Esto hace que el controlador cree una nueva conexión a la base de datos con cada llamada a la función. Esto puede ser costoso y provocar que su aplicación exceda los límites de conexión a la base de datos. Al definir un nuevo MongoClient, debe:

    1. Crea el objeto MongoClient una vez.

    2. Se debe almacenar el objeto para que la función pueda reutilizar el MongoClient entre invocaciones de funciones.

    El ejemplo de conexión reutiliza las conexiones de base de datos existentes para acelerar la comunicación con la base de datos y mantener el número de conexiones con la base de datos en un nivel razonable con respecto al tráfico de la aplicación.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3
  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta la guía de Especificación de opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si el driver toma una función de retorno como su último argumento, se debe establecer la propiedad callbackWaitsForEmptyEventLoop en el objeto de contexto de AWS Lambda en false.

    context.callbackWaitsForEmptyEventLoop = false;

    Esto permite que una función Lambda devuelva su resultado a quien la llama sin requerir que se cierre la conexión a la base de datos MongoDB. Establecer esta propiedad no es aplicable para controladores asíncronos.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para aprender más, consulta Herramientas para conectarse a MongoDB.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para más información, consulta Opciones de URI.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

    Para obtener más información, consulta Opciones de conexión.

  • Si hay una función Lambda que se conecta a un clúster particionado con muchas particiones, es posible que se experimenten problemas de rendimiento. Por ejemplo, con un clúster de diez particiones, el driver se conecta a las treinta instancias mongos por defecto. Se puede usar la opción srvMaxHosts en la cadena de conexión para establecer el número máximo de hosts a los que se conecta el driver. Para mejorar el rendimiento del driver, se debe configurar srvMaxHosts=3. Por ejemplo:

    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3
  • Se debe restringir el acceso a la red al clúster de Atlas.

    Conéctese a su clúster Atlas a través de una red privada utilizando un Conexión de interconexión de red entre su clúster Atlas y su Función AWS Lambda o, alternativamente, un punto final privado, para que pueda permitir solo direcciones IP privadas de su lista de acceso IP.

    Si no utiliza una red privada, considere conectarse a su clúster de Atlas a través de un gateway NAT con una dirección IP elástica asignada. De lo contrario, debe permitir que todas las direcciones IP (0.0.0.0/0) accedan a su clúster de servicios.

    Advertencia

    Agregar 0.0.0.0/0 a la lista de acceso IP permite el acceso al clúster desde cualquier lugar de la internet pública. Hay que garantizar estar usando credenciales fuertes para todos los usuarios de base de datos cuando se permita el acceso desde cualquier lugar.

Nota

Si se añade el CIDR 0.0.0.0/0 a la lista de acceso de un proyecto, Atlas envía un correo electrónico de alerta a todos los usuarios a los que se les haya otorgado un rol en el proyecto de forma directa o indirecta a través de la pertenencia al equipo (si al equipo se le otorga un rol en el proyecto).

  • Establecer maxIdleTimeMS en 60000 para cerrar automáticamente las conexiones después de 1 minuto de inactividad. Ajustar maxIdleTimeMS puede ayudar a reducir la ocurrencia de errores de tiempo de espera en las funciones sin servidor.

  • Configura el acceso unificado a AWS y utiliza la autenticación AWS IAM siempre que sea posible.

    Es posible realizar la conexión a los clústeres de Atlas usando roles de AWS IAM en lugar de codificar las credenciales en Lambda. Cualquiera que acceda al entorno de AWS Lambda puede ver las credenciales codificadas, lo que puede representar un riesgo de seguridad. Con la autenticación AWS IAM, Atlas accede a AWS Lambda a través de un rol de IAM asumido, por lo que no se necesitan credenciales en las cadenas de conexión.

    Atlas admite la autenticación AWS IAM para clústeres que ejecutan MongoDB versión 7.0 o superior. Recomendamos encarecidamente utilizar la autenticación de AWS IAM para las conexiones Lambda si el clúster cumple con los requisitos.

  • La cantidad de memoria asignada a una función Lambda por defecto es de 128 MB. Puedes configurar la cantidad de memoria asignada a una función Lambda, entre 128 MB y 10,240 MB. Asegúrate de asignar suficiente memoria. Aumenta la memoria para aumentar la cantidad de CPU virtual disponible y optimizar el rendimiento del driver de MongoDB. Para aprender más, consulta Memoria y potencia de cálculo.

  • Configure sus AWS_STS_REGIONAL_ENDPOINTS y AWS_REGION variables de entorno.

#include <mongoc/mongoc.h>
void lambda_handler ()
{
bson_error_t error;
mongoc_init();
// Parse URI
char *uri_string = "your-mongodb-atlas-connection-string";
mongoc_uri_t *uri = mongoc_uri_new_with_error (uri_string, &error);
if (!uri) {
fprintf (stderr, "Failed to parse URI: %s\n", error.message);
return;
}
// Create client
mongoc_client_t *client = mongoc_client_new_from_uri_with_error(uri, &error);
if (!client) {
fprintf(stderr, "Failed to create client: %s\n", error.message);
return;
}
// Perform client operations here
// Cleanup
mongoc_client_destroy(client);
mongoc_uri_destroy (uri);
mongoc_cleanup();
}
#include <aws/core/Aws.h>
#include <aws/lambda-runtime/runtime.h>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/options/client.hpp>
#include <mongocxx/options/server_api.hpp>
#include <mongocxx/exception/exception.hpp>
#include <cstdlib>
#include <iostream>
using namespace aws::lambda_runtime;
class ExampleAwsHandler
{
private:
mongocxx::client mongo_client;
client CreateMongoClient()
{
mongocxx::uri uri("mongodb://<hostname>:<port>/?authMechanism=MONGODB-AWS");
mongocxx::options::server_api server_api_options(mongocxx::options::server_api::version::k_version_1);
mongocxx::options::client client_options;
client_options.server_api_opts(server_api_options);
return client(uri, client_options);
}
public:
ExampleAwsHandler()
: mongo_client(CreateMongoClient())
{
}
std::string HandleRequest()
{
try
{
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;
auto db = mongo_client["my_database"];
auto command = make_document(kvp("hello", 1));
auto result = db.run_command(command.view());
return bsoncxx::to_json(result);
}
catch (const mongocxx::exception &e)
{
std::cerr << "MongoDB Exception: " << e.what() << std::endl;
return "{}";
}
}
};
static invocation_response my_handler(invocation_request const &)
{
ExampleAwsHandler handler;
std::string response = handler.HandleRequest();
return invocation_response::success(response, "application/json");
}
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
mongocxx::instance instance{};
run_handler(my_handler);
}
Aws::ShutdownAPI(options);
return 0;
}
string username = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID");
string password = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY");
string awsSessionToken = Environment.GetEnvironmentVariable("AWS_SESSION_TOKEN");
var awsCredentials =
new MongoCredential("MONGODB-AWS", new MongoExternalIdentity(username), new PasswordEvidence(password))
.WithMechanismProperty("AWS_SESSION_TOKEN", awsSessionToken);
var mongoUrl = MongoUrl.Create($"<MONGODB_URI>");
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClientSettings.Credential = awsCredentials;
mongoClientSettings.ServerApi = new ServerApi(ServerApiVersion.V1, strict: true);
return new MongoClient(mongoClientSettings);
private static MongoClient MongoClient { get; set; }
private static MongoClient CreateMongoClient()
{
var mongoClientSettings = MongoClientSettings.FromConnectionString($"<MONGODB_URI>");
mongoClientSettings.ServerApi = new ServerApi(ServerApiVersion.V1, strict: true);
return new MongoClient(mongoClientSettings);
}
static ShareMongoClientLambdaHandler()
{
MongoClient = CreateMongoClient();
}
public string HandleRequest(ILambdaContext context)
{
var database = MongoClient.GetDatabase("db");
var collection = database.GetCollection<BsonDocument>("coll");
var result = collection.Find(FilterDefinition<BsonDocument>.Empty).First();
return result.ToString();
}
import (
"context"
"os"
runtime "github.com/aws/aws-lambda-go/lambda"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
var client, err = mongo.Connect(options.Client().ApplyURI(os.Getenv("MONGODB_URI")))
func HandleRequest(ctx context.Context) error {
if err != nil {
return err
}
return client.Ping(context.TODO(), nil)
}
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.bson.Document;
public class ExampleAwsLambdaHandler implements RequestHandler<String, String> {
private final MongoClient client;
public ExampleAwsLambdaHandler() {
client = MongoClients.create(System.getenv("MONGODB_URI"));
}
@Override
public String handleRequest(final String input, final Context context) {
return client.getDatabase("admin").runCommand(new Document("ping", 1)).toJson();
}
}
import com.mongodb.kotlin.client.coroutine.MongoClient
import com.mongodb.kotlin.client.coroutine.MongoDatabase
import org.bson.Document
import kotlinx.coroutines.runBlocking
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
class ExampleAwsLambdaHandler : RequestHandler<String, String> {
private val client: MongoClient = MongoClient.create(System.getenv("MONGODB_URI"))
override fun handleRequest(input: String, context: Context): String = runBlocking {
val database: MongoDatabase = client.getDatabase("admin")
val command = Document("ping", 1)
val result = database.runCommand(command)
result.toJson()
}
}
import com.mongodb.kotlin.client.MongoClient
import com.mongodb.kotlin.client.MongoDatabase
import org.bson.Document
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
class ExampleAwsLambdaHandler : RequestHandler<String, String> {
private val client: MongoClient = MongoClient.create(System.getenv("MONGODB_URI"))
override fun handleRequest(input: String, context: Context): String {
val database: MongoDatabase = client.getDatabase("admin")
val command = Document("ping", 1)
val result = database.runCommand(command)
return result.toJson()
}
}
const { MongoClient } = require('mongodb');
// Get the URI for the cluster then set AWS_ACCESS_KEY_ID as the username in the
// URI and AWS_SECRET_ACCESS_KEY as the password, then set the appropriate auth
// options. Note that MongoClient now auto-connects so no need to store the connect()
// promise anywhere and reference it.
const client = new MongoClient(process.env.MONGODB_URI, {
auth: {
username: process.env.AWS_ACCESS_KEY_ID,
password: process.env.AWS_SECRET_ACCESS_KEY
},
authSource: '$external',
authMechanism: 'MONGODB-AWS'
});
module.exports.handler = async function () {
const databases = await client.db('admin').command({ listDatabases: 1 });
return {
statusCode: 200,
databases: databases
};
};
const { MongoClient } = require('mongodb');
// MongoClient now auto-connects so no need to store the connect()
// promise anywhere and reference it.
const client = new MongoClient(process.env.MONGODB_URI);
module.exports.handler = async function () {
const databases = await client.db('admin').command({ listDatabases: 1 });
return {
statusCode: 200,
databases: databases
};
};
import os
from pymongo import MongoClient
client = MongoClient(host=os.environ["MONGODB_URI"])
def lambda_handler(event, context):
return client.db.command("ping")
# Require the driver library.
require "mongo"
# Create a Mongo::Client instance using AWS IAM authentication.
# CRITICAL: You must create the client instance outside the handler
# so that the client can be reused across function invocations.
client = Mongo::Client.new([ENV.fetch("MONGODB_HOST")],
auth_mech: :aws,
user: ENV.fetch("AWS_ACCESS_KEY_ID"),
password: ENV.fetch("AWS_SECRET_ACCESS_KEY"),
auth_mech_properties: {
aws_session_token: ENV.fetch("AWS_SESSION_TOKEN"),
},
database: ENV.fetch("MONGODB_DATABASE"))
def lambda_handler(event:, context:)
# Use the client to return the name of the configured database.
client.database.name
end
# Require the driver library.
require "mongo"
# Create a Mongo::Client instance.
# CRITICAL: You must create the client instance outside the handler
# so that the client can be reused across function invocations.
client = Mongo::Client.new(ENV.fetch("MONGODB_URI"))
def lambda_handler(event:, context:)
# Use the client to return the name of the configured database.
client.database.name
end
use lambda_runtime::{service_fn, LambdaEvent};
use mongodb::{
bson::doc,
options::{AuthMechanism, ClientOptions, Credential},
Client,
};
use serde_json::Value;
use tokio::sync::OnceCell;
// Initialize a global static MongoDB Client with AWS authentication. The following environment
// variables should also be set: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and, optionally,
// AWS_SESSION_TOKEN.
static MONGODB_CLIENT: OnceCell<Client> = OnceCell::const_new();
async fn get_mongodb_client() -> &'static Client {
MONGODB_CLIENT
.get_or_init(|| async {
let uri = std::env::var("MONGODB_URI")
.expect("MONGODB_URI must be set to the URI of the MongoDB deployment");
let mut options = ClientOptions::parse(&uri)
.await
.expect("Failed to parse options from URI");
let credential = Credential::builder()
.mechanism(AuthMechanism::MongoDbAws)
.build();
options.credential = Some(credential);
Client::with_options(options).expect("Failed to create MongoDB Client")
})
.await
}
// Runs a ping operation on the "db" database and returns the response.
async fn handler(_: LambdaEvent<Value>) -> Result<Value, lambda_runtime::Error> {
let client = get_mongodb_client().await;
let response = client
.database("db")
.run_command(doc! { "ping": 1 })
.await?;
let json = serde_json::to_value(response)?;
Ok(json)
}
#[tokio::main]
async fn main() -> Result<(), lambda_runtime::Error> {
let service = service_fn(handler);
lambda_runtime::run(service).await?;
Ok(())
}
use lambda_runtime::{service_fn, LambdaEvent};
use mongodb::{bson::doc, Client};
use serde_json::Value;
use tokio::sync::OnceCell;
// Initialize a global static MongoDB Client.
static MONGODB_CLIENT: OnceCell<Client> = OnceCell::const_new();
async fn get_mongodb_client() -> &'static Client {
MONGODB_CLIENT
.get_or_init(|| async {
let uri = std::env::var("MONGODB_URI")
.expect("MONGODB_URI must be set to the URI of the MongoDB deployment");
Client::with_uri_str(uri)
.await
.expect("Failed to create MongoDB Client")
})
.await
}
// Runs a ping operation on the "db" database and returns the response.
async fn handler(_: LambdaEvent<Value>) -> Result<Value, lambda_runtime::Error> {
let client = get_mongodb_client().await;
let response = client
.database("db")
.run_command(doc! { "ping": 1 })
.await?;
let json = serde_json::to_value(response)?;
Ok(json)
}
#[tokio::main]
async fn main() -> Result<(), lambda_runtime::Error> {
let service = service_fn(handler);
lambda_runtime::run(service).await?;
Ok(())
}
import org.mongodb.scala.{MongoClient, Document}
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
class ExampleAwsLambdaHandler extends RequestHandler[String, String] {
private val client: MongoClient = MongoClient(System.getenv("MONGODB_URI"))
override def handleRequest(input: String, context: Context): String = {
val database = client.getDatabase("admin")
val command = Document("ping" -> 1)
val futureResult = database.runCommand(command).toFuture()
val result = Await.result(futureResult, Duration(30, "second"))
result.toJson()
}
}

Volver

Solucionar problemas

En esta página