什么原因导致 node.js 应用程序和 MongoDB ReplicaSet 中处理请求时出现 SocketException(9001)?

什么原因导致 node.js 应用程序和 MongoDB ReplicaSet 中处理请求时出现 SocketException(9001)?

我有一个简单的 node.js 应用程序,它对我的​​ ReplicaSet 进行一次调用连接调用。今天早些时候,一切实际上都运行良好,应用程序中没有任何变化,现在我的连接失败了(悄无声息),我在 mongod 日志中看到以下内容。

Thu Apr 18 17:16:56 [conn1782026] end connection 10.x.x.x:50720 (40 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50721 #1782027 (41 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50722 #1782028 (42 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50723 #1782029 (43 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50724 #1782030 (44 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50725 #1782031 (45 connections now open)
Thu Apr 18 17:16:57 [initandlisten] connection accepted from 10.x.x.x:50736 #1782032 (46 connections now open)
[conn1782028] SocketException handling request, closing client connection: 9001 socket exception [2] server [10.x.x.x:50722]

我还无法查明导致此问题的原因或如何解决它。

这是我的连接代码:

var _ = require("underscore");
var db_options = {
    db:{
            w:1,
            native_parser: false
        },
    server:{
        auto_reconnect:true,
        socketOptions: {}
    },
    replSet:{
        rs_name: "my_replset_name",
        readPreference: "secondary"
    },
    mongos: {}
};
db.client.connect("mongodb://server1:27017,server2:27017,server3:27017/my_database", db_options, function(err, _db){
    if(err){
        console.log(err);
    }else{
        _db.collection("my_collection", function(err, collection){
            collection.find({q:1}).toArray(function(err,item){
                if(err){
                    console.log(err);
                }else{
                    _.each(item, function(r){
                        if(!_.isEmpty(r)){
                            // do something with this item!
                            console.log(r._id);
                        }
                    });
                    console.log("Finished.");
                }
            });
        });
    }
});

我在 EC2 上运行我的 ReplicaSet,一切都可以成功地相互连接,有一个简单的 node.js 应用程序,可以对我的 ReplicaSet 进行一次调用连接调用 - 就像我说的,它起作用了,然后在没有任何通知的情况下停止了工作。

有人对此有任何见解吗?是什么原因造成的?如何预防?如何解决?

提前致谢。

答案1

根据提供的信息很难进行诊断,但一个可能的线索是您打开的连接数(数字从 1 - conn1 - 开始,每个新连接递增)。 conn1782026表示自启动以来您已打开近 180 万个连接。并发mongod连接数约为 40,我希望mongod非常需要很长时间才能看到打开和关闭的连接数。

如果没有,那么这可能就是发生了什么的提示。每次运行查询或类似操作时,您是否都会创建新连接?如果是这样,您可能需要调整代码以改为池化连接(请参阅各种这里的选项)。

现在,从理论上讲,无论如何您都应该能够做到这一点 - 本身拥有大量连接不会造成问题,但这里的流失量可能会产生意想不到的后果。尝试重新启动mongod,测试,如果仍然存在,请重新启动实例并再次测试。如果任何一个都可以解决问题,那么它不太可能与网络有关(系统重置将重置网络接口,因此仍然有很小的机会),即使它表现为套接字异常。

顺便说一句,如果你想了解你正在创建多少个连接,请看这里:

> db.serverStatus().connections
{ "current" : 1, "available" : 2047, "totalCreated" : NumberLong(1) }

totalCreatedmongod是特定进程或进程生命周期的计数器mongos。如果将其除以正常运行时间,还可以得到每秒创建的平均数等。

如果你想更进一步,你可以使用优秀的mtools绘制图表连接流失随着时间的推移,查看连接创建/销毁是否出现特别高的峰值。

如果重置没有任何效果,并且您仍然看到异常,那么是时候查看您的网络了。检查netstat -s(多个样本)的输出并查找递增重传和快速重传,运行ifconfig以查找接口上的错误、ping、traceroute 等 - 这些都是您尝试确定是否存在网络问题的常用方法。

相关内容