Javascript 重启后等待MongoDB就绪的正确方法是什么?

Javascript 重启后等待MongoDB就绪的正确方法是什么?,javascript,bash,mongodb,Javascript,Bash,Mongodb,我有一个失败的bash脚本。经检查,故障似乎是由于MongoDB在重启后立即被访问所致 例如,运行: mongo --eval "db.version()" 给出了预期的输出: MongoDB外壳版本:2.4.9 连接到:测试 2.4.9 运行时: service mongodb restart; mongo --eval "db.version()" 生成以下输出,重点是: mongodb停止/等待 mongodb启动/运行,进程1466 MongoDB外壳版本:2.4.9 连接到:测试

我有一个失败的bash脚本。经检查,故障似乎是由于MongoDB在重启后立即被访问所致

例如,运行:

mongo --eval "db.version()"
给出了预期的输出:

MongoDB外壳版本:2.4.9
连接到:测试
2.4.9

运行时:

service mongodb restart; mongo --eval "db.version()"
生成以下输出,重点是:

mongodb停止/等待
mongodb启动/运行,进程1466
MongoDB外壳版本:2.4.9
连接到:测试
10月25日星期六02:52:29.736错误:无法连接到src/mongo/shell/mongo.js:145上的服务器127.0.0.1:27017 异常:连接失败

因为服务器还没有准备好

在执行bash脚本期间,等待MongoDB实际就绪的正确方法是什么

  • 服务mongodb status
    不是解决方案,因为它报告的是服务的状态,而不是数据库本身

  • 重复执行nc-zlocalhost 27017,直到其退出代码变为0为止,都可以工作,但我不确定是否有缺点(以某种方式运行无限循环?)


要在不连接任何数据库的情况下启动mongo解释器:

mongo --nodb
在mongo解释器中,您可以执行:

var conn;
try
{
    conn = new Mongo("localhost:27017");
}
catch(Error)
{
    //print(Error);
}
while(conn===undefined)
{
    try
    {
        conn = new Mongo("localhost:27017");
    }
    catch(Error)
    {
        //print(Error);
    }
    sleep(100);
}
DB = conn.getDB("test");
Result = DB.runCommand('buildInfo');
print(Result.version);
使用上面的2,您可以将后面的部分放在一个类似Script.js的文件中,然后执行以下操作:

mongo --nodb Script.js

编辑:在那里,你完全忘记了你真正想要的是版本。为您解决了这个问题。

基于@Magnitus的回答,我添加了一个超时和可配置的连接字符串

var conn;
var interval = 100;   // 100 Milliseconds polling
var timeout  = 10000; // 10 Seconds timeout
var startTime = new Date();
connectionUrl = connectionUrl.split('/')[2];

if (connectionUrl.indexOf('@') !== -1) {
  // Has auth (doesn't need auth for test connection)
  connectionUrl = connectionUrl.split('@')[1];
}

while(conn === undefined) {
  try {
    var elapsed = (new Date() - startTime);
    print("Attempting to connect to " + connectionUrl + " elapsed: " + elapsed + "ms");
    conn = new Mongo(connectionUrl);
  } catch(error) {
    print(error);

    if ((new Date() - startTime) >= timeout) {
      print("ERROR: Failed to establish connection within timeout (" + timeout + "ms)");
      quit(1);
    } else {
      sleep(interval);
    }
  }
}

print("MongoDB connection established in " + (new Date() - startTime) + "ms");
你可以这样称呼它:

export MONGO_URL="mongo://<user>:<pass>@<host>:<port>/<database>"
mongo --nodb wait_for_mongo.js --eval "connectionUrl=\"$MONGO_URL\""
export MONGO\u URL=“MONGO://:@:”
mongo--nodb wait_for_mongo.js--eval“connectionUrl=\”$mongo_URL\“”

脚本只需要host:port来测试连接,因此
MONGO\u URL=”mongo://localhost“
足以测试连接。

与其在脚本中修复此问题,不如在mongo init脚本/upstart unit/systemd服务中修复它(至少在我的场景中是这样)

对于systemd:

ExecStartPost=/bin/sh -c 'while ! /usr/bin/mongo --eval "db.version()" > /dev/null 2>&1; do sleep 0.1; done'

@Arseni如果只需要验证和最小消息返回,请使用quit()并放弃标准错误和输出消息

警告-您可能需要设置一个超时-如果mongo没有出现或出现网络问题怎么办

while true
 do

   mongo --quiet --eval "quit()"  1>/dev/zero 2>&1  
   rc=$?    
   if [ $rc -ne 0 ] 
     then sleep 2 
   else 
     break
   fi

 done
 

注意:除非运行带有--nodb标志的脚本,否则这将不起作用。如果数据库关闭,该命令只会阻塞连接错误并输出错误代码1。