You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python版AWS Lambda连接本地MongoDB报连接拒绝错误排查

问题场景

基于AWS SAM搭建Python版本AWS Lambda函数,本地机器安装部署MongoDB,尝试建立Lambda与MongoDB的连接,初始实现代码如下:

import json
import pymongo
client = pymongo.MongoClient('mongodb://localhost:27017/')
mydb = client['Employee']

def lambda_handler(event, context):
    information = mydb.employeeInformation
    record = {
        'FirstName' : 'Rehan',
        'LastName' : 'CH',
        'Department' : "IT" 
    }
    information.insert_one(record)
    print("Record added")

    return {
        "statusCode": 200,
        "body": json.dumps(
            {
                "message": "hello world",
                # "location": ip.text.replace("\n", "")
             }
    ),
}

使用sam local invoke命令本地运行函数时,抛出如下连接错误:

[ERROR] ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 62b16aa14a95a3e56eb0e7cb, topology_type: Unknown, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('localho    raise ServerSelectionTimeoutError(, line 227, in _select_servers_looprtn_support
问题根因
  • 核心原因是网络命名空间不匹配:sam local invoke运行Lambda时,会把函数跑在独立的Docker容器中,代码里写的localhost指向容器自身的内部网络,不是宿主机的回环地址,所以代码实际是在尝试连接容器内部的27017端口,自然找不到部署在宿主机上的MongoDB服务,触发连接拒绝。
  • 代码存在额外隐患:MongoDB客户端初始化写在全局作用域,冷启动阶段就会尝试建立连接,后续部署到线上AWS环境时容易出现连接数溢出、连接复用失效的问题。
解决方法

按以下步骤操作即可修复问题:

  1. 修正MongoDB连接地址
    本地SAM调试时,Docker容器提供了特殊域名host.docker.internal用于访问宿主机上的服务,把原连接串mongodb://localhost:27017/替换为mongodb://host.docker.internal:27017/即可。
    如果你使用Linux系统运行Docker,执行sam local invoke时需要追加参数,手动映射宿主机地址:
    sam local invoke --add-host host.docker.internal:host-gateway
    
  2. 确认本地MongoDB服务状态
    先在宿主机终端执行mongosh(老版本用mongo命令)连接localhost:27017,确认MongoDB服务正常启动,没有防火墙规则拦截Docker网段对27017端口的访问。如果你的MongoDB配置了bindIp仅允许127.0.0.1访问,可临时修改配置为bindIp: 0.0.0.0(仅本地调试用,上线前务必收紧访问权限)。
  3. 优化连接逻辑(避免线上隐患)
    把MongoDB连接改为懒加载模式,仅在第一次调用函数时初始化连接,同时增加连接可用性检测,修正后完整代码如下:

import json
import pymongo
from pymongo.errors import ConnectionFailure

mongo_client = None
mydb = None

def init_mongo_conn():
global mongo_client, mydb
# 本地调试用host.docker.internal,部署到线上时替换为实际MongoDB地址
mongo_client = pymongo.MongoClient(
'mongodb://host.docker.internal:27017/',
serverSelectionTimeoutMS=5000
)
# 检测连接是否正常
mongo_client.admin.command('ping')
mydb = mongo_client['Employee']

def lambda_handler(event, context):
if not mongo_client:
init_mongo_conn()
information = mydb.employeeInformation
record = {
'FirstName' : 'Rehan',
'LastName' : 'CH',
'Department' : "IT"
}
information.insert_one(record)
print("Record added")

return {
    "statusCode": 200,
    "body": json.dumps({
        "message": "Record inserted successfully"
    })
}
改完后重新执行`sam local invoke`即可正常连通MongoDB完成数据插入。

---
内容的提问来源于stack exchange,提问作者M Rehan
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:31:14