Dieser Artikel ist ** Teil.5 ** von Artikeln im Zusammenhang mit ** Erfahren Sie, wie Sie Docker mithilfe der Django + MySQL-Umgebungskonstruktion verwenden ** Es entspricht.
In diesem Artikel werden wir versuchen, das Problem des ** Verbindungsfehlers aufgrund der Startreihenfolge ** zu lösen, das auftreten kann, wenn mehrere abhängige Dienste mit "Docker-Compose" ausgeführt werden.
In den Artikeln bis Letztes Mal legen wir die Umgebungskonstruktion von Django
+ MySQL
mit Docker-Compose fest.
Wenn ich versuche, den Django-Server mit "$ docker-compose up" zu starten, nachdem die Grundeinstellungen vorgenommen wurden,
** Obwohl die "MySQL" -Seite nicht bereit ist, versucht "Django", eine Verbindung zur "DB" herzustellen, und die Situation wird nicht mit einem Verbindungsfehler fortgesetzt **. Es kann enden.
Im Moment handelt es sich um ein Problem, das nur zum Zeitpunkt der Erstausführung auftritt. Wenn Sie auf der MySQL-Seite auf die Vorbereitung warten, diese einmal manuell abbrechen und "$ docker-compose up" erneut ausführen, ist die Verbindung erfolgreich, aber in Zukunft Um das gleiche Problem und den gleichen Ärger bei Änderungen im Arbeitsprozess zu vermeiden, ** überlegen Sie, ob Sie im Voraus Gegenmaßnahmen ergreifen können **.
Wenn die Verbindung mit der Datenbank fehlschlägt, wird der folgende Fehler gesendet und der Container auf der Django-Seite wird starr.
# (Auszug)
djst_django | MySQLdb._exceptions.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
djst_django | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
Es scheint ein Fehler zu sein, der gesendet wird, wenn versucht wird, eine Verbindung zu einer nicht vorhandenen Datenbank herzustellen. Mit anderen Worten, in diesem Fall besteht das Problem darin, dass die Datenbank noch nicht bereit ist. Überlegen wir uns also, ob wir die Reihenfolge anpassen können, indem wir warten, bis dies auf irgendeine Weise möglich ist.
Übrigens Docker empfiehlt offiziell das Lösen mit einem Shell-Skript, aber diesmal ist es die Codierung von "Python" und die Verbindung von "mysqlclient". Zum Üben werde ich eine dedizierte Python-Datei vorbereiten und versuchen, sie zu lösen **.
Die folgenden Dateien werden im Verzeichnis config
vorbereitet.
config/wait_for_db.py
import os
import MySQLdb
from time import sleep
from pathlib import Path
os.chdir(Path(__file__).parent)
from local_settings import DB_NAME, DB_USER, DB_PASSWORD
count_to_try = 0
LIMIT_OF_COUNT = 20 #Passen Sie den Wert nach Bedarf an
def check_connection(count, limit):
"""
docker-Compose up Funktion zur Zeitanpassung zur Laufzeit.
"""
try:
conn = MySQLdb.connect(
unix_socket = "/var/run/mysqld/mysqld.sock",
user=DB_USER,
passwd=DB_PASSWORD,
host="db",
port=3306,
db=DB_NAME,
)
except MySQLdb._exceptions.OperationalError as e:
count += 1
print("Waiting for MySQL... (", count, "/ 20 )")
sleep(3)
if count < limit:
check_connection(count, limit)
else:
print(e)
print("Failed to connect mySQL.")
else:
print("Connected!\n")
conn.close()
exit()
if __name__ == "__main__":
check_connection(count_to_try, LIMIT_OF_COUNT)
Als nächstes werde ich über den Inhalt des Codes schreiben.
Installieren Sie zunächst die erforderlichen Bibliotheken und Pakete.
config/wait_for_db.py
import os
import MySQLdb
from time import sleep
from pathlib import Path
os.chdir(Path(__file__).parent)
from local_settings import DB_NAME, DB_USER, DB_PASSWORD
Verschieben Sie für local_settings.py
das Verzeichnis mit os.chdir (Pfad (__ file__) .parent)
und importieren Sie es dann.
Definieren Sie als Nächstes die Variablen.
config/wait_for_db.py
count_to_try = 0
LIMIT_OF_COUNT = 20 #Passen Sie den Wert nach Bedarf an
count_to_try
dient zum Zählen der Häufigkeit, mit der die später beschriebene Funktion aufgerufen wird, und LIMIT_OF_COUNT
ist das Nummernlimit. In der Funktion wird eine bedingte Verzweigung durchgeführt, sodass die Datei nach 20-maliger Wiederholung beendet wird. Passen Sie diesen Wert nach Bedarf an.
Für den Inhalt der Hauptfunktion check_connection
,
try
eine Verbindung zu MySQL herzustellen.config/wait_for_db.py
try:
conn = MySQLdb.connect(
unix_socket = "/var/run/mysqld/mysqld.sock",
user=DB_USER,
passwd=DB_PASSWORD,
host="db",
port=3306,
db=DB_NAME,
)
Das "unix_socket" der "try" -Anweisung ist der Socket, der für die Verbindung verwendet wird. Dies wird jedoch im Protokoll angezeigt, wenn "$ docker-compose up" ausgeführt wird, sodass Sie es kopieren können. Der Rest ist der gleiche wie der, der beim letzten Mal von Django
gesetzt wurde.
.
config/wait_for_db.py
except MySQLdb._exceptions.OperationalError as e:
count += 1
print("Waiting for MySQL... (", count, "/ 20 )")
sleep(3)
if count < limit:
check_connection(count, limit)
else:
print(e)
print("Failed to connect mySQL.")
Bei der Anweisung "Except" wird die Anzahl der Versuche gezählt und ausgegeben, dann 3 Sekunden gewartet, und wenn sie 20 Mal erreicht ist, wird der Fehlerinhalt ausgegeben und die Datei beendet. Die Obergrenze wird festgelegt, um eine Endlosschleife zu verhindern, wenn ein tatsächlicher Verbindungsfehler vorliegt. .
config/wait_for_db.py
else:
print("Connected!\n")
conn.close()
exit()
Wenn die versuchte Verbindung in der Anweisung "try" erfolgreich ist (=> **, wenn MySQL bereit ist **), erklärt die Anweisung "else" die Verbindung für erfolgreich, schließt die Verbindung und beendet die Datei. ..
Wenn Sie die Anweisung "else" übergeben können, sollte der nächste Befehl "runserver" unverzüglich ausgeführt werden. .
config/wait_for_db.py
if __name__ == "__main__":
check_connection(count_to_try, LIMIT_OF_COUNT)
Der letzte Teil ist if __name__ ==" __main__ ":
, dh ** "wenn diese Datei direkt ausgeführt wird" **, wird die Funktion check_connection
gelesen. Das Argument ist die am Anfang definierte Variable.
Fügen Sie abschließend eine Beschreibung in den Befehl von docker-compose.yml ein, damit diese Datei ausgeführt wird, bevor der Server ausgeführt wird.
docker-compose.yml
command: >
bash -c "
pip install -r requirements.txt &&
python config/wait_for_db.py &&
python manage.py runserver 0.0.0.0:8000
"
Jetzt haben Sie ein Programm **, das auf die Ausführung des Befehls ** runserver wartet, um MySQL einzurichten.
Wenn ich tatsächlich "$ docker-compose up" ausführe ...
# (Auszug)
djst_django | Waiting for MySQL... ( 1 / 20 )
# (Unterlassung...)
djst_mysql | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
djst_django | Connected!
# (Unterlassung...)
djst_django | Starting development server at http://0.0.0.0:8000/
djst_django | Quit the server with CONTROL-C.
Nachdem ich gewartet hatte, konnte ich den Django-Server nach Bestätigung der Verbindung sicher starten.
(Wiederholen Sie aus dem vorherigen Artikel, aufgrund der Einstellung ist die tatsächliche Funktionsprüfung nicht die angezeigte http: //0.0.0.0: 8000 /
, sondern ** http://172.0.0.1 Dies erfolgt ab: 8000 /
oder http: // localhost: 8000 /
**.)
Mit dem oben Gesagten wurde der ursprüngliche Zweck der ** Anpassung des Container-Startzeitpunkts zwischen abhängigen Diensten ** erreicht. Wenn Sie Vorschläge haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten.
Dieses Mal habe ich es für das Training in Python geschrieben, aber ich möchte das Shell-Skript herausfordern, damit es frei verwendet werden kann.
(Sie können von hier aus zur ersten Seite zurückkehren ↓.) Erfahren Sie, wie Sie Docker mithilfe der Django + MySQL-Umgebungskonstruktion verwenden
Danke für Ihren Besuch.
Recommended Posts