簡體   English   中英

如何檢查 mongodb 是否已啟動並准備好接受來自 bash 腳本的連接?

[英]how to check if mongodb is up and ready to accept connections from bash script?

我有一個 bash shell 腳本,它在嘗試mongorestore之前做了很多事情。

我想確保不僅 MongoDB 已啟動,而且在我嘗試恢復之前,它也已准備好接受連接。

現在,我看到的是,mongo 進程已啟動,但在准備好接受連接之前,需要 45 秒以上的時間進行初始設置(設置日志文件等)。 理想情況下,我想在循環中繼續測試連接,並且只有當我能夠連接時,我才想運行mongorestore

有人可以告訴我如何在 Bash 中執行此操作或為我指明正確的方向嗎?

要像您建議的那樣在循環中測試連接,

until nc -z localhost 27017
do
    sleep 1
done

使用 MongoDB 工具的解決方案。 在 docker 容器或您不想安裝nc類似內容中很有用。

until mongo --eval "print(\"waited for connection\")"
  do
    sleep 60
  done

根據那個人的回答。

我最近遇到了同樣的問題。 我決定將mongod配置為將所有輸出記錄到日志文件中,然后在循環中等待檢查​​日志文件,直到我們看到一些表明 mongod 已准備就緒的輸出。

這是我們需要等待的示例日志文件輸出行:

Tue Dec  3 14:25:28.217 [initandlisten] waiting for connections on port 27017

這是我想出的 bash 腳本:

#!/bin/bash

# Initialize a mongo data folder and logfile
mkdir -p /data/db
touch /var/log/mongodb.log

# Start mongodb with logging
# --logpath    Without this mongod will output all log information to the standard output.
# --logappend  Ensure mongod appends new entries to the end of the logfile. We create it first so that the below tail always finds something
/usr/bin/mongod  --quiet --logpath /var/log/mongodb.log --logappend &

# Wait until mongo logs that it's ready (or timeout after 60s)
COUNTER=0
grep -q 'waiting for connections on port' /var/log/mongodb.log
while [[ $? -ne 0 && $COUNTER -lt 60 ]] ; do
    sleep 2
    let COUNTER+=2
    echo "Waiting for mongo to initialize... ($COUNTER seconds so far)"
    grep -q 'waiting for connections on port' /var/log/mongodb.log
done

# Now we know mongo is ready and can continue with other commands
...

請注意,腳本不會永遠等待,它會在 60 秒后超時 - 根據您的用例,您可能需要也可能不需要。

雖然 Tom 的答案在大多數情況下都可以很好地工作,但如果您使用-e標志運行腳本,它可能會失敗。 我的意思是你在最頂部使用set -e運行你的腳本。 為什么? 因為 Tom 的回答依賴於前一個命令的退出狀態,在這種情況下grep -q如果找不到所需的字符串就會失敗,因此整個腳本都會失敗。 -e標志文檔提供了有關如何避免此問題的線索:

如果失敗的命令是緊跟在 while 或 until 關鍵字之后的命令列表的一部分、if 語句中測試的一部分、在 && 或 || 中執行的任何命令的一部分,則 shell 不會退出列表除了最后一個 && 或 || 之后的命令,管道中除最后一個之外的任何命令,或者如果命令的返回狀態正在用 ! 反轉。

因此,一種解決方案是使 grep 命令成為 while 條件的一部分。 但是,由於他使用--logappend選項運行 mongodb,因此搜索字符串可能會作為上次運行的結果出現。 我將另一個人的答案與湯姆的答案結合起來,效果非常好:

# Wait until mongo logs that it's ready (or timeout after 60s)
COUNTER=0
while !(nc -z localhost 27017) && [[ $COUNTER -lt 60 ]] ; do
    sleep 2
    let COUNTER+=2
    echo "Waiting for mongo to initialize... ($COUNTER seconds so far)"
done

我發現使用 tomcat 是最好的解決方案,因為它實際上測試是否有東西在聽。

在創建用戶之前,我需要在 Docker 中運行的 Mongo 進行初始化。 我結合了湯姆和比約恩的答案。 這是我正在使用的腳本:

#!/bin/bash

# Wait until Mongo is ready to accept connections, exit if this does not happen within 30 seconds
COUNTER=0
until mongo --host ${MONGO_HOST} --eval "printjson(db.serverStatus())"
do
  sleep 1
  COUNTER=$((COUNTER+1))
  if [[ ${COUNTER} -eq 30 ]]; then
    echo "MongoDB did not initialize within 30 seconds, exiting"
    exit 2
  fi
  echo "Waiting for MongoDB to initialize... ${COUNTER}/30"
done

# Connect to the MongoDB and execute the create users script
mongo ${FWRD_API_DB} /root/create-user.js --host ${MONGO_HOST} -u ${MONGO_ROOT_USER} -p ${MONGO_ROOT_PASSWORD} --authenticationDatabase admin

可能的 Docker 解決方案:

鑒於docker_id對我來說它可以讀取docker_id docker logs例如:

until [ $(docker logs --tail all $docker_id | grep "waiting for connections on port" | wc -l) -gt 0 ]; do
    printf '.'
    sleep 1
done

然后繼續任何依賴於 mongo 的任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM