Aus dem Leben mit Kubernetes: Wie wir DBMS (und nicht nur) aus Überprüfungsumgebungen in statische Umgebungen entfernt haben



Hinweis : Dieser Artikel erhebt keinen Anspruch auf bewährte Vorgehensweise. Es beschreibt die Erfahrung einer bestimmten Implementierung einer Infrastrukturaufgabe im Hinblick auf die Verwendung von Kubernetes und Helm, die bei der Lösung verwandter Probleme hilfreich sein kann.

Die Verwendung von Überprüfungsumgebungen in CI / CD kann sowohl für Entwickler als auch für Systemingenieure sehr nützlich sein. Lassen Sie uns zunächst die allgemeinen Vorstellungen über sie synchronisieren:

  1. Überprüfungsumgebungen können aus separaten Zweigen in Git-Repositorys erstellt werden, die von Entwicklern definiert wurden (sogenannte Feature-Zweige).
  2. Sie können separate DBMS-Instanzen, Warteschlangenprozessoren, Caching-Dienste usw. haben. - im Allgemeinen alles für die vollständige Reproduktion der Produktionsumgebung.
  3. Sie ermöglichen eine parallele Entwicklung und beschleunigen die Veröffentlichung neuer Funktionen in der Anwendung erheblich. Gleichzeitig können täglich Dutzende solcher Umgebungen erforderlich sein, weshalb die Geschwindigkeit ihrer Erstellung von entscheidender Bedeutung ist.

An der Schnittstelle zwischen dem zweiten und dem dritten Punkt treten häufig Schwierigkeiten auf: Da die Infrastruktur sehr unterschiedlich ist, können ihre Komponenten für eine lange Zeit bereitgestellt werden. Diese aufgewendete Zeit umfasst beispielsweise das Wiederherstellen der Datenbank aus einer bereits vorbereiteten Sicherung *. Der Artikel handelt von der faszinierenden Art und Weise, wie wir einst ein solches Problem gelöst haben.

* Übrigens, speziell über große Datenbank-Dumps in diesem Zusammenhang haben wir bereits in dem Material über die Beschleunigung der Bootstrap-Datenbank geschrieben .)

Das Problem und der Weg, es zu lösen


In einem der Projekte wurde uns die Aufgabe übertragen, "einen einzigen Einstiegspunkt für Entwickler und QS-Ingenieure zu schaffen". Diese Formulierung verbarg technisch folgendes:

  1. Um die Arbeit der QS-Ingenieure und einiger anderer Mitarbeiter zu vereinfachen, nehmen Sie alle in der Überprüfung verwendeten Datenbanken (und entsprechenden vhosts) in einer separaten - statischen - Umgebung heraus. Aus den im Projekt vorherrschenden Gründen war diese Art der Interaktion mit ihnen optimal.
  2. Reduzieren Sie den Zeitaufwand für die Erstellung einer Überprüfungsumgebung. Der gesamte Prozess ihrer Erstellung von Grund auf ist impliziert, d.h. einschließlich Datenbankklonen, Migrationen usw.

Unter dem Gesichtspunkt der Implementierung besteht das Hauptproblem darin, die Idempotenz beim Erstellen und Löschen von Überprüfungsumgebungen sicherzustellen. Um dies zu erreichen, haben wir den Mechanismus zum Erstellen von Überprüfungsumgebungen geändert, indem wir zuerst die PostgreSQL-, MongoDB- und RabbitMQ-Dienste in eine statische Umgebung migriert haben. Statisch bezieht sich auf eine solche „permanente“ Umgebung, die nicht auf Anforderung des Benutzers erstellt wird (wie dies bei Überprüfungsumgebungen der Fall ist).

Wichtig! Der Ansatz mit einer statischen Umgebung ist alles andere als ideal - für seine spezifischen Mängel siehe das Ende des Artikels. Wir teilen diese Erfahrung jedoch im Detail, da sie mehr oder weniger auf andere Aufgaben anwendbar sein kann und gleichzeitig als Argument bei der Erörterung von Fragen des Infrastrukturdesigns dient.

Also, die Reihenfolge der Aktionen in der Implementierung:

  • Beim Erstellen einer Überprüfungsumgebung sollte Folgendes einmal geschehen: Erstellen von Datenbanken in zwei DBMS (MongoDB und PostgreSQL), Wiederherstellen von Datenbanken aus einer Sicherung / Vorlage und Erstellen von vhost in RabbitMQ. Dies erfordert eine bequeme Möglichkeit zum Laden aktueller Speicherauszüge. (Wenn Sie zuvor Überprüfungsumgebungen hatten, haben Sie höchstwahrscheinlich bereits eine vorgefertigte Lösung dafür.)
  • Nach Abschluss der Überprüfungsumgebung müssen Sie die Datenbank und den virtuellen Host in RabbitMQ löschen.

In unserem Fall arbeitet die Infrastruktur im Rahmen von Kubernetes (mit Helm). Daher waren für die Ausführung der oben genannten Aufgaben Helmhaken ausgezeichnet . Sie können sowohl vor dem Erstellen aller anderen Komponenten in der Helm-Version als auch nach deren Entfernung ausgeführt werden. Deshalb:

  • Für die Initialisierungsaufgabe wird ein Hook verwendet pre-install, um sie zu starten, bevor alle Ressourcen in der Version erstellt werden.
  • für die Löschaufgabe ein Hook post-delete.

Kommen wir zu den Implementierungsdetails.

Praktische Anwendung


In der Originalversion verwendete dieses Projekt nur einen Job, der aus drei Containern bestand. Dies ist natürlich nicht ganz praktisch, da das Ergebnis ein großes Manifest ist, das kitschig und schwer zu lesen ist. Deshalb haben wir es in drei kleine Jobs aufgeteilt.

Das Folgende ist eine Auflistung für PostgreSQL, und die anderen beiden (MongoDB und RabbitMQ) sind in der Manifeststruktur identisch:

{{- if .Values.global.review }}
---
apiVersion: batch/v1
kind: Job
metadata:
  name: db-create-postgres-database
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-weight": "5"
spec:
  template:
    metadata:
      name: init-db-postgres
    spec:
      volumes:
      - name: postgres-scripts
        configMap:
          defaultMode: 0755
          name: postgresql-configmap
      containers:
      - name: init-postgres-database
        image: private-registry/postgres 
        command: ["/docker-entrypoint-initdb.d/01-review-load-dump.sh"]
        volumeMounts:
        - name: postgres-scripts
          mountPath: /docker-entrypoint-initdb.d/01-review-load-dump.sh
          subPath: review-load-dump.sh
        env:
{{- include "postgres_env" . | indent 8 }}
      restartPolicy: Never
{{- end }}

Kommentare zum Inhalt des Manifests:

  1. Job review-. review CI/CD Helm- (. if .Values.global.review ).
  2. Job — , ConfigMap. , , . , hook-weight.
  3. cURL , PostgreSQL, .
  4. PostgreSQL : , shell- .

PostgreSQL


Das interessanteste ist das bereits in der Liste erwähnte Shell-Skript ( review-load-dump.sh). Was sind die allgemeinen Optionen zum Wiederherstellen einer Datenbank in PostgreSQL?

  1. "Standard" -Wiederherstellung von der Sicherung;
  2. Wiederherstellung mit Vorlagen .

In unserem Fall liegt der Unterschied zwischen den beiden Ansätzen hauptsächlich in der Geschwindigkeit, mit der eine Datenbank für die neue Umgebung erstellt wird. Im ersten Fall laden wir den Datenbankspeicherauszug und stellen ihn mit wieder her pg_restore. Und bei uns geschieht dies langsamer als bei der zweiten Methode, sodass die entsprechende Auswahl getroffen wurde.

Verwenden der zweiten Option ( Wiederherstellung mit Vorlagen) Sie können die Datenbank auf physischer Ebene klonen, ohne Daten aus dem Container in einer anderen Umgebung remote an sie zu senden. Dies verkürzt die Wiederherstellungszeit. Es gibt jedoch eine Einschränkung: Sie können keine Datenbank klonen, zu der noch aktive Verbindungen bestehen. Da wir Stage als statische Umgebung verwenden (und keine separate Überprüfungsumgebung), müssen wir eine zweite Datenbank erstellen und diese in eine Vorlage konvertieren und täglich aktualisieren (z. B. morgens). Dafür wurde ein kleiner CronJob vorbereitet:

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: update-postgres-template
spec:
  schedule: "50 4 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  startingDeadlineSeconds: 600
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          imagePullSecrets:
          - name: registrysecret
          volumes:
          - name: postgres-scripts
            configMap:
              defaultMode: 0755
              name: postgresql-configmap-update-cron
          containers:
          - name: cron
            command: ["/docker-entrypoint-initdb.d/update-postgres-template.sh"]
          image: private-registry/postgres 
            volumeMounts:
            - name: postgres-scripts
              mountPath: /docker-entrypoint-initdb.d/update-postgres-template.sh
              subPath: update-postgres-template.sh
            env:
{{- include "postgres_env" . | indent 8 }}

Das vollständige ConfigMap-Manifest, das das Skript enthält, ist höchstwahrscheinlich nicht sehr sinnvoll (in den Kommentaren angeben, falls dies nicht der Fall ist). Stattdessen werde ich das Wichtigste geben - ein Bash-Skript:

#!/bin/bash -x

CREDENTIALS="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}/postgres"

psql -d "${CREDENTIALS}" -w -c "REVOKE CONNECT ON DATABASE ${POSTGRES_DB_TEMPLATE} FROM public"
psql -d "${CREDENTIALS}" -w -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '${POSTGRES_DB_TEMPLATE}'"

curl --fail -vsL ${HOST_FORDEV}/latest_${POSTGRES_DB_STAGE}.psql -o /tmp/${POSTGRES_DB}.psql

psql -d "${CREDENTIALS}" -w -c "ALTER DATABASE ${POSTGRES_DB_TEMPLATE} WITH is_template false allow_connections true;"
psql -d "${CREDENTIALS}" -w -c "DROP DATABASE ${POSTGRES_DB_TEMPLATE};" || true
psql -d "${CREDENTIALS}" -w -c "CREATE DATABASE ${POSTGRES_DB_TEMPLATE};" || true
pg_restore -U ${POSTGRES_USER} -h ${POSTGRES_HOST} -w -j 4 -d ${POSTGRES_DB_TEMPLATE} /tmp/${POSTGRES_DB}.psql

psql -d "${CREDENTIALS}" -w -c "ALTER DATABASE ${POSTGRES_DB_TEMPLATE} WITH is_template true allow_connections false;"

rm -v /tmp/${POSTGRES_DB}.psql

Sie können mehrere Datenbanken gleichzeitig aus einer Vorlage ohne Konflikte wiederherstellen. Die Hauptsache ist, dass Datenbankverbindungen verboten werden sollten und die Datenbank selbst eine Vorlage sein sollte. Dies erfolgt im vorletzten Schritt.

Das Manifest mit dem Shell-Skript zum Wiederherstellen der Datenbank stellte sich wie folgt heraus:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgresql-configmap
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
  review-load-dump.sh: |
    #!/bin/bash -x
    
 
 
    CREDENTIALS="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}/postgres"

    if [ "$( psql -d "${CREDENTIALS}" -tAc "SELECT CASE WHEN EXISTS (SELECT * FROM pg_stat_activity WHERE datname = '${POSTGRES_DB}' LIMIT 1) THEN 1 ELSE 0 END;" )" = '1' ]
      then
          echo "Open connections has been found in ${POSTGRES_DB} database, will drop them"
          psql -d "${CREDENTIALS}" -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '${POSTGRES_DB}' -- AND pid <> pg_backend_pid();"
      else
          echo "No open connections has been found ${POSTGRES_DB} database, skipping this stage"
    fi

    psql -d "${CREDENTIALS}" -c "DROP DATABASE ${POSTGRES_DB}"

    if [ "$( psql -d "${CREDENTIALS}" -tAc "SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB}'" )" = '1' ]
      then
          echo "Database ${POSTGRES_DB} still exists, delete review job failed"
          exit 1
      else
          echo "Database ${POSTGRES_DB} does not exist, skipping"
    fi


    psql ${CREDENTIALS} -d postgres -c 'CREATE DATABASE ${POSTGRES_DB} TEMPLATE "loot-stage-copy"'

Anscheinend sind sie hier beteiligt hook-delete-policy. Details zur Anwendung dieser Richtlinien finden Sie hier . In dem angegebenen Manifest verwenden wir before-hook-creation,hook-succeeded, um die folgenden Anforderungen zu erfüllen: Löschen Sie das vorherige Objekt, bevor Sie einen neuen Hook erstellen, und löschen Sie es nur, wenn der Hook erfolgreich war.

Wir werden die Datenbank in dieser ConfigMap löschen:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgresql-configmap-on-delete
  annotations:
    "helm.sh/hook": "post-delete, pre-delete"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation
data:
  review-delete-db.sh: |
    #!/bin/bash -e

    CREDENTIALS="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}/postgres"

    psql -d "${CREDENTIALS}" -w postgres -c "DROP DATABASE ${POSTGRES_DB}"

Obwohl wir es in eine separate ConfigMap verschoben haben, kann es in eine reguläre ConfigMap eingefügt werden command. Schließlich kann es zu einem Einzeiler gemacht werden, ohne das Erscheinungsbild des Manifests selbst zu verkomplizieren.

Wenn die Option mit PostgreSQL-Vorlagen aus irgendeinem Grund nicht passt oder nicht passt, können Sie mithilfe der Sicherung zum oben genannten "Standard" -Wiederherstellungspfad zurückkehren . Der Algorithmus wird trivial sein:

  1. Jede Nacht wird eine Datenbanksicherung durchgeführt, damit diese aus dem lokalen Netzwerk des Clusters heruntergeladen werden kann.
  2. Zum Zeitpunkt der Erstellung der Überprüfungsumgebung wird die Datenbank geladen und aus dem Speicherauszug wiederhergestellt.
  3. Wenn der Speicherauszug bereitgestellt wird, werden alle anderen Aktionen ausgeführt.

In diesem Fall sieht das Wiederherstellungsskript ungefähr wie folgt aus:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgresql-configmap
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
  review-load-dump.sh: |
    #!/bin/bash -x

    CREDENTIALS="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}/postgres"
    psql -d "${CREDENTIALS}" -w -c "DROP DATABASE ${POSTGRES_DB}" || true
    psql -d "${CREDENTIALS}" -w -c "CREATE DATABASE ${POSTGRES_DB}"

    curl --fail -vsL ${HOST_FORDEV}/latest_${POSTGRES_DB_STAGE}.psql -o /tmp/${POSTGRES_DB}.psql

    psql psql -d "${CREDENTIALS}" -w -c "CREATE EXTENSION ip4r;"
    pg_restore -U ${POSTGRES_USER} -h ${POSTGRES_HOST} -w -j 4 -d ${POSTGRES_DB} /tmp/${POSTGRES_DB}.psql
    rm -v /tmp/${POSTGRES_DB}.psql

Das Verfahren entspricht dem, was oben bereits beschrieben wurde. Die einzige Änderung ist das Entfernen der psql-Datei, nachdem alle Arbeiten hinzugefügt wurden.

Hinweis : Sowohl im Wiederherstellungsskript als auch im Deinstallationsskript wird die Datenbank jedes Mal gelöscht. Dies geschieht, um mögliche Konflikte bei der Neuerstellung der Überprüfung zu vermeiden: Sie müssen sicherstellen, dass die Datenbank wirklich gelöscht wird. Dieses Problem kann möglicherweise auch durch Hinzufügen eines Flags --cleanim Dienstprogramm gelöst werden. Seien Sie pg_restorejedoch vorsichtig: Dieses Flag löscht nur die Daten der Elemente, die sich im Speicherauszug selbst befinden. In unserem Fall funktioniert diese Option also nicht.

Als Ergebnis haben wir einen funktionierenden Mechanismus erhalten, der weitere Verbesserungen erfordert (bis hin zum Ersetzen von Bash-Skripten durch eleganteren Code). Wir werden sie außerhalb des Geltungsbereichs des Artikels belassen (obwohl Kommentare zum Thema natürlich willkommen sind).

Mongodb


Die nächste Komponente ist MongoDB. Die Hauptschwierigkeit dabei ist, dass für dieses DBMS die Option zum Kopieren der Datenbank (wie in PostgreSQL) eher nominell besteht, weil:

  1. Er ist in einem veralteten Zustand .
  2. Nach den Ergebnissen unserer Tests haben wir keinen großen Unterschied in der Zeit der Datenbankwiederherstellung im Vergleich zur üblichen festgestellt mongo_restore. Ich stelle jedoch fest, dass die Tests als Teil eines Projekts durchgeführt wurden - in Ihrem Fall können die Ergebnisse völlig unterschiedlich sein.

Es stellt sich heraus, dass bei einem großen Datenbankvolumen ein ernstes Problem auftreten kann: Wir sparen Zeit beim Wiederherstellen der Datenbank in PgSQL, stellen aber gleichzeitig den Speicherauszug in Mongo für eine sehr lange Zeit wieder her. Zum Zeitpunkt des Schreibens und im Rahmen der vorhandenen Infrastruktur haben wir drei Möglichkeiten gesehen (sie können übrigens kombiniert werden):

  1. Die Wiederherstellung kann beispielsweise lange dauern, wenn sich Ihr DBMS in einem Netzwerkdateisystem befindet (in Fällen ohne Produktionsumgebung). Anschließend können Sie das DBMS einfach von der Bühne auf einen separaten Knoten übertragen und den lokalen Speicher verwenden. Da dies keine Produktion ist, ist die Geschwindigkeit der Erstellung einer Überprüfung für uns kritischer.
  2. Sie können jede Jobwiederherstellung in einem separaten Pod speichern, sodass Sie Migrationen und andere Prozesse, die vom Betrieb des DBMS abhängen, vorab ausführen können. So sparen wir Zeit, indem wir sie im Voraus ausfüllen.
  3. Manchmal können Sie die Größe des Speicherauszugs reduzieren, indem Sie alte / irrelevante Daten löschen - soweit es ausreicht, nur die Datenbankstruktur zu belassen. Dies gilt natürlich nicht für Fälle, in denen ein vollständiger Speicherauszug erforderlich ist (z. B. für QS-Testaufgaben).

Wenn Sie keine schnellen Überprüfungsumgebungen erstellen müssen, können alle beschriebenen Schwierigkeiten ignoriert werden.

Da wir die Datenbank nicht ähnlich wie PgSQL kopieren können, werden wir den ersten Weg gehen, d. H. Standardwiederherstellung von der Sicherung. Der Algorithmus ist der gleiche wie bei PgSQL. Dies ist leicht zu erkennen, wenn Sie sich die Manifeste ansehen:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-scripts-on-delete
  annotations:
    "helm.sh/hook": "post-delete, pre-delete"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation
data:
  review-delete-db.sh: |
    #!/bin/bash -x

    mongo ${MONGODB_NAME} --eval "db.dropDatabase()" --host ${MONGODB_REPLICASET}/${MONGODB_HOST}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-scripts
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
  review-load-dump.sh: |
    #!/bin/bash -x

    curl --fail -vsL ${HOST_FORDEV}/latest_${MONGODB_NAME_STAGE}.gz -o /tmp/${MONGODB_NAME}.gz

    mongo ${MONGODB_NAME} --eval "db.dropDatabase()" --host ${MONGODB_REPLICASET}/${MONGODB_HOST}
    mongorestore --gzip --nsFrom "${MONGODB_NAME_STAGE}.*" --nsTo "${MONGODB_NAME}.*" --archive=/tmp/${MONGODB_NAME}.gz --host ${MONGODB_REPLICASET}/${MONGODB_HOST}

Hier gibt es ein wichtiges Detail. In unserem Fall befindet sich MongoDB im Cluster und Sie müssen sicherstellen, dass die Verbindung immer zum Primärknoten erfolgt . Wenn Sie beispielsweise den ersten Host im Quorum angeben, wechselt dieser möglicherweise nach einiger Zeit von primär zu sekundär, wodurch die Erstellung einer Datenbank verhindert wird. Daher müssen Sie keine Verbindung zu einem Host, sondern sofort zu ReplicaSet herstellen und alle darin enthaltenen Hosts auflisten. Allein aus diesem Grund müssen Sie MongoDB als StatefulSet erstellen, damit die Hostnamen immer gleich sind (ganz zu schweigen davon, dass MongoDB von Natur aus eine Stateful-Anwendung ist). Bei dieser Option wird garantiert, dass Sie eine Verbindung zum Primärknoten herstellen.

Für MongoDB löschen wir auch die Datenbank, bevor wir die Überprüfung erstellen - dies erfolgt aus den gleichen Gründen wie in PostgreSQL.

Letzte Nuance: Da sich die zu überprüfende Datenbank in derselben Umgebung wie die Stufe befindet, ist für die geklonte Datenbank ein separater Name erforderlich. Wenn der Speicherauszug keine BSON-Datei ist, tritt der folgende Fehler auf:

the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead

Daher werden im obigen Beispiel --nsFromund verwendet --nsTo.

Wir haben keine anderen Probleme mit der Genesung festgestellt. Am Ende möchte ich nur hinzufügen, dass die Dokumentation für copyDatabaseMongoDB hier verfügbar ist - falls Sie diese Option ausprobieren möchten.

Rabbitmq


Die letzte Anwendung auf unserer Anforderungsliste war RabbitMQ. Es ist ganz einfach: Sie müssen im Namen des Benutzers, mit dem die Anwendung eine Verbindung herstellen soll, einen neuen vhost erstellen. Und dann löschen.

Manifest zum Erstellen und Entfernen von vhosts:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: rabbitmq-configmap
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
  rabbitmq-setup-vhost.sh: |
    #!/bin/bash -x

    /usr/local/bin/rabbitmqadmin -H ${RABBITMQ_HOST} -u ${RABBITMQ_USER} -p ${RABBITMQ_PASSWORD} declare vhost name=${RABBITMQ_VHOST}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: rabbitmq-configmap-on-delete
  annotations:
    "helm.sh/hook": "post-delete, pre-delete"
    "helm.sh/hook-weight": "1"
    "helm.sh/hook-delete-policy": before-hook-creation
data:
  rabbitmq-delete-vhost.sh: |
    #!/bin/bash -x

    /usr/local/bin/rabbitmqadmin -H ${RABBITMQ_HOST} -u ${RABBITMQ_USER} -p ${RABBITMQ_PASSWORD} delete vhost name=${RABBITMQ_VHOST}

Mit großen Schwierigkeiten in RabbitMQ sind wir (bisher?) Nicht begegnet. Im Allgemeinen kann der gleiche Ansatz für alle anderen Dienste gelten, die keine kritische Datenbindung aufweisen.

Nachteile


Warum behauptet diese Entscheidung nicht, „Best Practices“ zu sein?

  1. Es stellt sich heraus, dass es sich um einen einzelnen Fehlerpunkt in Form einer Bühnenumgebung handelt.
  2. Wenn eine Anwendung in einer Stage-Umgebung nur in einem Replikat ausgeführt wird, sind wir noch stärker von dem Host abhängig, auf dem diese Anwendung ausgeführt wird. Dementsprechend nimmt mit zunehmender Anzahl von Überprüfungsumgebungen die Last auf dem Knoten proportional zu, ohne dass diese Last ausgeglichen werden kann.

Diese beiden Probleme konnten unter Berücksichtigung der Fähigkeiten der Infrastruktur eines bestimmten Projekts nicht vollständig gelöst werden. Potenzielle Schäden können jedoch durch Clustering (Hinzufügen neuer Knoten) und vertikale Skalierung minimiert werden.

Fazit


Mit der Entwicklung der Anwendung und der zunehmenden Anzahl von Entwicklern steigt früher oder später die Belastung der Überprüfungsumgebungen und es werden neue Anforderungen hinzugefügt. Für Entwickler ist es wichtig, die nächsten Änderungen in der Produktion so schnell wie möglich bereitzustellen. Um dies zu ermöglichen, benötigen wir dynamische Überprüfungsumgebungen, die die Entwicklung „parallel“ machen. Infolgedessen wächst die Belastung der Infrastruktur und die Zeit für die Erstellung solcher Umgebungen nimmt zu.

Dieser Artikel wurde basierend auf realen und ziemlich spezifischen Erfahrungen geschrieben. Nur in Ausnahmefällen isolieren wir Dienste in statischen Umgebungen, und hier ging es speziell um ihn. Dank dieser notwendigen Maßnahme konnten wir die Entwicklung und das Debuggen der Anwendung beschleunigen - dank der Möglichkeit, schnell Überprüfungsumgebungen von Grund auf neu zu erstellen.

Als wir anfingen, diese Aufgabe zu erledigen, schien es sehr einfach zu sein, aber als wir daran arbeiteten, fanden wir viele Nuancen. Sie wurden im letzten Artikel zusammengestellt: Obwohl sie nicht universell sind, können sie als Beispiel für die Grundlage / Inspiration ihrer eigenen Entscheidungen zur Beschleunigung von Überprüfungsumgebungen dienen.

PS


Lesen Sie auch in unserem Blog:


All Articles