对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用 AWS Lambda 管理连接

使用以下最佳实践来正确管理AWS Lambda和Atlas之间的连接:

  • 在 AWS Lambda处理程序函数之外定义MongoDB服务器的客户端。

    请勿在每次调用函数时都定义新的客户端对象。这样做会导致驱动程序在每次函数调用时创建一个新的数据库连接。这可能会产生高昂的成本,并可能导致应用程序超出数据库连接限制。为获得最佳性能,请遵循以下准则:

    1. 创建一次客户端对象。

    2. 存储该对象,以便函数可以跨函数调用重复使用客户端。

    连接示例重复使用现有数据库连接来加快与数据库的通信,并将数据库连接计数保持在相对于应用程序流量的合理水平。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:
    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3
  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅指定连接选项指南。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您的处理程序将回调作为最后一个参数,请将 AWS Lambda Context对象上的 callbackWaitsForEmptyEventLoop属性设立为 false。

    context.callbackWaitsForEmptyEventLoop = false;

    这允许Lambda函数将其结果返回给调用者,而无需关闭MongoDB 数据库连接。设置此属性不适用于异步处理程序。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 要将无服务器PHP应用程序部署到 AWS Lambda,请使用 Bref框架。要安装必备组件并配置 Bref,请按照 Bref 文档中的设置教程进行操作。

    接下来,您可以创建项目目录,安装MongoDB和 Bref 依赖项,并通过运行以下命令来初始化无服务器配置:

    mkdir bref-mongodb-app && cd bref-mongodb-app
    composer init
    composer require bref/bref bref/extra-php-extensions mongodb/mongodb
    vendor/bin/bref init

    最后,将MongoDB PHP扩展添加到您的项目中。 bref/extra-php-extensions Composer包提供了一个无服务器框架插件,该插件将MongoDB PHP扩展添加为Lambda层。更新 serverless.yml文件以包含以下突出显示的行:

    plugins:
    - ./vendor/bref/bref
    - ./vendor/bref/extra-php-extensions
    functions:
    api:
    handler: index.php
    runtime: php-85-fpm
    layers:
    - ${bref-extra:mongodb2-php-85}
  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅用于连接到MongoDB 的工具。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解详情,请参阅 URI 选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:

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

    要学习;了解更多信息,请参阅连接选项。

  • 如果您有一个连接到具有许多分片的分片集群的Lambda函数,则可能会遇到性能问题。示例,对于有 10 个分片的集群,驾驶员默认连接到所有 30 个 mongos 实例。您可以在连接字符串中使用 srvMaxHosts 选项来设立驾驶员连接到的主机的最大数量。要提高驾驶员性能,设立srvMaxHosts=3。示例:
    mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3

注意

如果您将任何 IPv4 /0 CIDR(例如 0.0.0.0/0 或 10.0.0.0/0)添加到项目访问列表中,Atlas 会向所有直接被授予该项目角色的用户发送告警邮件;对于通过团队成员身份间接获得项目角色的用户(前提是该团队已被授予项目角色),Atlas 也会发送告警邮件。

  • 将 maxIdleTimeMS 设置为 60000,可在 1 分钟的空闲时间后自动关闭连接。调整 maxIdleTimeMS 有助于减少无服务器函数发生超时错误的概率。
  • 设置统一 AWS 访问权限,并尽可能使用 AWS IAM身份验证。

    您可以使用 AWS IAM 角色连接到Atlas集群,而不是在Lambda中硬编码您的凭证。任何访问您的 AWS Lambda环境的人都可以查看硬编码凭证,这可能会带来安全风险。使用 AWS IAM身份验证, Atlas可通过假定的 IAM角色访问 AWS Lambda ,因此您无需在连接字符串中凭证。

    Atlas支持对运行MongoDB 7.0 或更高版本的集群进行 AWS IAM身份验证。如果您的集群符合要求,则强烈建议对Lambda连接使用 AWS IAM身份验证。

  • 分配给Lambda函数的内存量默认为 128 MB。您可以在 128 MB 到 10 240 MB 之间配置分配给Lambda函数的内存量。确保分配足够的内存。增加内存以增加可用虚拟 CPU 的数量并提高MongoDB驾驶员性能。要学习;了解更多信息,请参阅内存和计算能力。

  • 设置 AWS_STS_REGIONAL_ENDPOINTS 和 AWS_REGION 环境变量。

#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
};
};

配置 AWS IAM身份验证后,从Atlas用户界面复制连接字符串。从连接字符串中删除 <AWS access key>:<AWS secret key> 部分,因为驾驶员会从环境变量中读取这些凭证。在项目的 serverless.yml文件中,将 MONGODB_URI 环境变量设立为此修改后的连接字符串,如以下代码所示:

provider:
environment:
MONGODB_URI: "<connection string without credentials>"

将 index.php文件的内容替换为以下代码:

require 'vendor/autoload.php';
use MongoDB\Client;
// Create the MongoDB client outside the handler function
$client = new Client(getenv('MONGODB_URI'));
function handler($event, $context) {
global $client;
$database = $client->getDatabase('admin');
$result = $database->command(['ping' => 1]);
return [
'statusCode' => 200,
'body' => json_encode($result)
];
}

要部署应用程序,运行以下命令:

serverless deploy
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()
}
}
给本页内容打分