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

OpenWhisk动作连接MongoDB超时问题排查求助

问题:OpenWhisk动作连接MongoDB超时,本地命令行/Node程序正常运行

在开发机上通过jar包运行OpenWhisk,本地Node程序和MongoDB命令行客户端都能正常连接MongoDB,但执行OpenWhisk动作时出现查询超时错误。

报错信息

执行curl调用动作时返回超时错误:

curl -u $tok "http://172.17.0.1:3233/api/v1/namespaces/_/actions/openwhiskmongo?blocking=true&result=true" -X POST -H "Content-Type: application/json" -d '{"username":"jonboy"}'
{"error":{"message":"Operation users.findOne() buffering timed out after 10000ms","name":"MongooseError","stack":"MongooseError: Operation users.findOne() buffering timed out after 10000ms\n    at Timeout.<anonymous> (/nodejsAction/hTFYlZze/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:153:23)\n    at listOnTimeout (internal/timers.js:557:17)\n    at processTimers (internal/timers.js:500:7)"}}

本地连接验证正常

命令行连接MongoDB成功

mongo mongodb://172.17.0.1
MongoDB shell version v4.4.17
connecting to: mongodb://172.17.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9777739e-0a81-4ef4-852a-a19a515ac376") }
MongoDB server version: 4.4.17
---
The server generated these startup warnings when booting: 
        2022-11-21T21:32:14.551-05:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
        2022-11-21T21:32:16.601-05:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
>

Docker网络配置信息

宿主机docker0网卡配置:

ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:efff:fecc:f630  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ef:cc:f6:30  txqueuelen 0  (Ethernet)
        RX packets 153  bytes 11410 (11.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 278  bytes 7650054 (7.6 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Docker bridge网络详情:

[
    {
        "Name": "bridge",
        "Id": "441a18a8d66ef7e29aaae1f2d5fee8b5e2f2edf39200b54a91f0df8b17407a46",
        "Created": "2022-11-19T09:03:56.78026462-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "13d0e2d487f03d2c806a917199857eefd77d9fb216eb9c68647ec5d7e93810e0": {
                "Name": "wsk0_243_prewarm_nodejs14",
                "EndpointID": "938de84937bfe214486713b4490645145a76f85cbff06f7ac49904beba9d8699",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

OpenWhisk动作代码

openmongowhisk.js

const mongoose = require('mongoose');

async function main(args) {
    require('./config/database');
    require('./models/user');
    const User = mongoose.model('User');

    const name = args && args.username;
    var result = 'not initialized';

    var user = await User.findOne({username: name}).exec();

    if (user) {
      result = 'found';
    } else {
      result = 'not found';
    }

    return { user: user, result: result };
}

exports.main = main;

config/database.js

const mongoose = require('mongoose');

const devConnection = "mongodb://172.17.0.1";

mongoose.connect(devConnection, {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

mongoose.connection.on('connected', () => {
    console.log('Database connected');
});

models/user.js

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    id: String,
    username: String,
});

mongoose.model('User', UserSchema);

解决思路

  • 检查MongoDB绑定地址:确认MongoDB配置文件(mongod.conf)中的bindIp设置为0.0.0.0,而非仅127.0.0.1。如果只绑定localhost,Docker容器无法通过172.17.0.1访问MongoDB服务,修改后重启MongoDB。

  • 等待数据库连接建立后执行查询:当前代码中,引入database.js后直接发起查询,但mongoose.connect是异步操作,可能连接未完成就执行查询导致超时。修改database.js返回连接Promise,在main函数中等待连接成功:

    // 修改config/database.js
    const mongoose = require('mongoose');
    
    const devConnection = "mongodb://172.17.0.1";
    
    const connectDB = async () => {
      try {
        await mongoose.connect(devConnection, {
          useNewUrlParser: true,
          useUnifiedTopology: true
        });
        console.log('Database connected');
      } catch (err) {
        console.error('Database connection failed:', err);
        throw err;
      }
    };
    
    module.exports = connectDB;
    
    // 修改openmongowhisk.js的main函数
    async function main(args) {
        const connectDB = require('./config/database');
        await connectDB(); // 等待连接建立
        require('./models/user');
        const User = mongoose.model('User');
    
        const name = args && args.username;
        var result = 'not initialized';
    
        var user = await User.findOne({username: name}).exec();
    
        if (user) {
          result = 'found';
        } else {
          result = 'not found';
        }
    
        return { user: user, result: result };
    }
    
  • 增强连接配置参数:在mongoose.connect中添加超时、重试参数,提升连接稳定性:

    mongoose.connect(devConnection, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      connectTimeoutMS: 5000,    // 连接超时时间
      socketTimeoutMS: 45000,    // 套接字超时时间
      retryWrites: true,         // 重试写操作
      retryReads: true           // 重试读操作
    });
    
  • 测试容器到宿主机的连通性:进入OpenWhisk的Node容器,测试能否访问宿主机的27017端口:

    # 进入容器
    docker exec -it wsk0_243_prewarm_nodejs14 bash
    # 测试ping连通性
    ping 172.17.0.1
    # 测试27017端口是否开放
    telnet 172.17.0.1 27017
    

    如果不通,检查宿主机防火墙是否拦截了27017端口,或者Docker的icc(容器间通信)配置是否正常。

  • 处理容器复用的连接失效问题:OpenWhisk的预热身容器可能会复用,若数据库连接已断开,需重新连接。在查询前检查连接状态:

    async function main(args) {
        const mongoose = require('mongoose');
        const connectDB = require('./config/database');
        // 检查连接状态,未连接则重新连接
        if (mongoose.connection.readyState !== 1) {
          await connectDB();
        }
        require('./models/user');
        const User = mongoose.model('User');
    
        // 后续查询逻辑...
    }
    

内容的提问来源于stack exchange,提问作者Jonboy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:01:22