Tutorial 3: Dienst-zu-Dienst-Kommunikation¶
Einführung¶
In diesem Tutorial erstellen Sie einen Snowpark Container Services-Jobdienst, der mit dem Echo-Dienst kommuniziert, den Sie in Tutorial 1 erstellt haben. Wenn der Jobdienst ausgeführt wird, sendet er eine POST-Anforderung an die Echo-Dienst-URL (die Sie in der Dienstspezifikation angeben) mit einer „Hello“-Zeichenfolge im Anforderungstext. Der Echo-Dienst gibt eine Antwort mit der Zeichenfolge „Bob said Hello“ (Bob sagte Hallo) im Antworttext zurück. Sie greifen auf die Protokolle des Jobdienstcontainers zu, um zu überprüfen, ob die Kommunikation erfolgreich war.
Dieses Tutorial besteht aus zwei Teilen:
Teil 1: Jobdienst erstellen und testen. Sie laden den für dieses Tutorial bereitgestellten Code herunter und befolgen die schrittweise Anleitung:
Jobdienstcode für dieses Tutorial herunterladen
Docker-Image für Snowpark Container Services erstellen und Image in Repository im eigenen Konto hochladen
Job-Spezifikationsdatei mit den Container-Konfigurationsinformationen für Snowflake im Stagingbereich bereitstellen. Neben dem Namen des Images, das zum Starten eines Containers verwendet werden soll, enthält die Spezifikationsdatei auch die Umgebungsvariable (
SERVICE_URL
) für die Echo-Dienst-URL. Der Anwendungscode liest diese Umgebungsvariable, um Anforderungen an den Echo-Dienst zu senden.Jobdienst ausführen. Mit dem Befehl EXECUTE JOB SERVICE können Sie den Jobdienst ausführen, indem Sie die Spezifikationsdatei und den Computepool angeben, in dem Snowflake den Container ausführen kann. Und schließlich können Sie auf die Protokolle des Jobdienstcontainers zugreifen, um zu überprüfen, ob die Kommunikation zwischen Jobdienst und Dienst erfolgreich war.
Teil 2: Erläuterungen zum Jobdienstcode. Dieser Abschnitt bietet eine Übersicht zum Dienstcode und zeigt auf, wie die verschiedenen Komponenten zusammenarbeiten.
Voraussetzungen¶
Schließen Sie Tutorial 1 ab, und überprüfen Sie, ob der Echo-Dienst ausgeführt wird.
SELECT SYSTEM$GET_SERVICE_STATUS('echo_service', 10);
1: Dienstcode herunterladen¶
Zum Erstellen eines Jobdienstes wird ein Code (eine Python-Anwendung) bereitgestellt.
Laden Sie
SnowparkContainerServices-Tutorials.zip
herunter.Entpacken Sie den Inhalt, der ein Verzeichnis für jedes Tutorial enthält. Das Verzeichnis
Tutorial-3
enthält die folgenden Dateien:service_to_service.py
Dockerfile
service_to_service_spec.yaml
2: Image erstellen und hochladen¶
Erstellen Sie ein Image für die linux/amd64-Plattform, die von Snowpark Container Services unterstützt wird, und laden Sie das Image dann in das Image-Repository in Ihrem Konto hoch (siehe Grundlegende Einrichtung).
Sie benötigen Informationen zum Repository (die Repository-URL und den Hostnamen der Registry), bevor Sie das Image erstellen und hochladen können. Weitere Informationen dazu finden Sie unter Registry und Repositorys.
Informationen zum Repository abrufen
Um die Repository-URL zu erhalten, führen Sie den SQL-Befehl SHOW IMAGE REPOSITORIES aus.
SHOW IMAGE REPOSITORIES;
Die URL ist in der Spalte
repository_url
der Ausgabe enthalten. Siehe folgendes Beispiel:<orgname>-<acctname>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository
Der Hostname in der Repository-URL ist der Name des Registry-Hosts. Siehe folgendes Beispiel:
<orgname>-<acctname>.registry.snowflakecomputing.com
Image erstellen und in das Repository hochladen
Öffnen Sie ein Terminalfenster, und wechseln Sie in das Verzeichnis, das die entpackten Dateien enthält.
Um ein Docker-Image zu erstellen, führen Sie den folgenden Befehl
docker build
mithilfe der Docker-CLI aus. Beachten Sie, dass der Befehl das aktuelle Arbeitsverzeichnis (.) alsPATH
für die Dateien angibt, die für das Erstellen des Images verwendet werden sollen.docker build --rm --platform linux/amd64 -t <repository_url>/<image_name> .
Für
image_name
verwenden Sieservice_to_service:latest
:
Beispiel
docker build --rm --platform linux/amd64 -t myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/service_to_service:latest .
Laden Sie das Image in das Repository in Ihrem Snowflake-Konto hoch. Damit Docker ein Image in Ihrem Namen in Ihr Repository hochladen kann, müssen Sie zunächst Docker mit der Registry authentifizieren.
Um Docker bei der Snowflake-Registrierung zu authentifizieren, führen Sie den folgenden Befehl aus.
docker login <registry_hostname> -u <username>
Geben Sie dabei für
username
Ihren Snowflake-Benutzernamen an. Docker fordert Sie zur Eingabe Ihres Kennworts auf.
Führen Sie den folgenden Befehl aus, um das Image hochzuladen:
docker push <repository_url>/<image_name>
Beispiel
docker push myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/service_to_service:latest
3: Spezifikationsdatei im Stagingbereich bereitstellen¶
Um Ihre Dienstspezifikationsdatei (
service_to_service_spec.yaml
) in den Stagingbereich hochzuladen, verwenden Sie eine der folgenden Optionen:Die Snowsight-Weboberfläche. Eine Anleitung dazu finden Sie unter Auswahl eines internen Stagingbereichs für lokale Dateien.
Die SnowSQL-CLI. Führen Sie den folgenden PUT-Befehl aus:
PUT file://<absolute-path-to-spec.yaml> @tutorial_stage AUTO_COMPRESS=FALSE OVERWRITE=TRUE;
Der Befehl setzt OVERWRITE=TRUE, sodass Sie die Datei bei Bedarf erneut hochladen können (z. B. wenn Sie einen Fehler in Ihrer Spezifikationsdatei behoben haben). Wenn der PUT-Befehl erfolgreich ausgeführt wurde, werden Informationen zu der hochgeladenen Datei ausgegeben.
4: Jobdienst ausführen¶
Jetzt sind Sie bereit, den von Ihnen erstellen Snowflake-Jobdienst zu testen. Während der Jobdienst ausgeführt wird, erfasst Snowflake alle Daten, die Ihr Code im Container an die Standardausgabe oder den Standardfehler ausgibt, als Protokolleinträge. Sie können die Systemfunktion SYSTEM$GET_SERVICE_LOGS
verwenden, um auf die Protokolleinträge zuzugreifen. Weitere Informationen dazu finden Sie unter Snowpark Container Services: Zusätzliche Hinweise zu Diensten.
Um einen Jobdienst zu starten, führen Sie den Befehl EXECUTE JOB SERVICE aus:
EXECUTE JOB SERVICE IN COMPUTE POOL tutorial_compute_pool NAME=tutorial_db.data_schema.tutorial3_job_service FROM @tutorial_stage SPEC='service_to_service_spec.yaml';
Beachten Sie Folgendes:
FROM und SPEC geben den Namen des Stagingbereichs bzw. den Namen der Dienstspezifikationsdatei an.
COMPUTE_POOL stellt die Computeressourcen bereit, auf denen Snowflake den Jobdienst ausführt.
Snowflake führt den in der Spezifikationsdatei angegebenen Container aus. Der Container liest den Wert der Umgebungsvariablen
SERVICE_URL
(http://echo-service:8000/echo
) und sendet eine Anforderung an den Echo-Dienst an Port 8000 im HTTP-Pfad/echo
.Snowflake startet den Jobdienst und gibt die folgende Ausgabe zurück:
+------------------------------------------------------------------------+ | status | |------------------------------------------------------------------------| | Job TUTORIAL3_JOB_SERVICE completed successfully with status: DONE | +------------------------------------------------------------------------+
Beachten Sie, dass die Antwort den Namen des Jobdienstes enthält.
(optional) Nach Beendigung des Jobdienstes können Sie weitere Informationen zu dem ausgeführten Jobdienst abrufen. Dies ist nützlich für die Fehlersuche bei Fehlschlagen des Jobdienstes. Um den Status des Jobdienstes abzurufen, rufen Sie die Funktion SYSTEM$GET_SERVICE_STATUS – Veraltet auf:
CALL SYSTEM$GET_SERVICE_STATUS('TUTORIAL3_JOB_SERVICE');
Beispielausgabe:
[ { "status":"DONE", "message":"Container finished", "containerName":"main", "instanceId":"0", "serviceName":"TUTORIAL3_JOB_SERVICE", "image":"myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/service_to_service:latest", "restartCount":0, "startTime":"2023-01-01T00:00:00Z" } ]
Um die Jobdienst-Protokolle zu lesen, rufen Sie SYSTEM$GET_SERVICE_LOGS auf:
CALL SYSTEM$GET_SERVICE_LOGS('tutorial_3_job_service', 0, 'main');
main
ist der Name des Containers, aus dem Sie das Protokoll abrufen. Diesen Containernamen verwenden Sie in der Dienstspezifikationsdatei zur Angabe des Containers.Beispielprotokoll:
+--------------------------------------------------------------------------------------------------------------------------+ | SYSTEM$GET_JOB_LOGS | |--------------------------------------------------------------------------------------------------------------------------| | service-to-service [2023-04-29 21:52:09,208] [INFO] Calling http://echo-service:8000/echo with input Hello | | service-to-service [2023-04-29 21:52:09,212] [INFO] Received response from http://echo-service:8000/echo: Bob said Hello | +--------------------------------------------------------------------------------------------------------------------------+
5: Bereinigen¶
Snowflake erhebt Gebühren für die Computepool-Knoten, die für Ihr Konto aktiv sind. (Siehe Verwenden von Computepools). Um unerwünschte Gebühren zu vermeiden, stoppen Sie zunächst alle Dienste, die derzeit in einem Computepool ausgeführt werden. Anschließend können Sie den Computepool entweder anhalten (wenn Sie ihn später wieder verwenden möchten) oder ihn löschen.
Stoppen Sie alle Dienste und Jobdienste im Computepool.
ALTER COMPUTE POOL tutorial_compute_pool STOP ALL;
Löschen Sie den Computepool.
DROP COMPUTE POOL tutorial_compute_pool;
Sie können auch die Image-Registry (alle Images entfernen) und den internen Stagingbereich (Spezifikationen entfernen) bereinigen.
DROP IMAGE REPOSITORY tutorial_repository;
DROP STAGE tutorial_stage;
6: Überprüfen des Jobdienstcodes¶
In diesem Abschnitt werden die folgenden Themen behandelt:
Untersuchen der bereitgestellten Dateien: Untersuchen Sie die verschiedenen Codedateien, mit denen der Jobdienst implementiert wird.
Lokales Erstellen und Testen eines Images. Erfahren Sie, wie Sie das Docker-Image lokal testen, bevor Sie es in ein Repository in Ihrem Snowflake-Konto hochladen.
Untersuchen der bereitgestellten Dateien¶
Die heruntergeladene ZIP-Datei enthält die folgenden Dateien:
service_to_service.py
Dockerfile
service_to_service_spec.yaml
Dieser Abschnitt bietet eine Übersicht darüber, wie der Code den Jobdienst implementiert.
Datei „service_to_service.py“¶
import json
import logging
import os
import requests
import sys
SERVICE_URL = os.getenv('SERVICE_URL', 'http://localhost:8080/echo')
ECHO_TEXT = 'Hello'
def get_logger(logger_name):
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
handler.setFormatter(
logging.Formatter(
'%(name)s [%(asctime)s] [%(levelname)s] %(message)s'))
logger.addHandler(handler)
return logger
logger = get_logger('service-to-service')
def call_service(service_url, echo_input):
logger.info(f'Calling {service_url} with input {echo_input}')
row_to_send = {"data": [[0, echo_input]]}
response = requests.post(url=service_url,
data=json.dumps(row_to_send),
headers={"Content-Type": "application/json"})
message = response.json()
if message is None or not message["data"]:
logger.error('Received empty response from service ' + service_url)
response_row = message["data"][0]
if len(response_row) != 2:
logger.error('Unexpected response format: ' + response_row)
echo_reponse = response_row[1]
logger.info(f'Received response from {service_url}: ' + echo_reponse)
if __name__ == '__main__':
call_service(SERVICE_URL, ECHO_TEXT)
Wenn der Jobdienst ausgeführt wird:
Snowflake verwendet den in der Spezifikationsdatei angegebenen Wert, um die Umgebungsvariable SERVICE_URL im Container festzulegen.
Der Code liest die Umgebungsvariable.
SERVICE_URL = os.getenv('SERVICE_URL', 'http://localhost:8080/echo').
Die Funktion
call_service()
verwendetSERVICE_URL
zur Kommunikation mit dem Echo-Dienst.
Datei „Dockerfile“¶
Diese Datei enthält alle Befehle, um ein Image mit Docker zu erstellen.
ARG BASE_IMAGE=python:3.10-slim-buster
FROM $BASE_IMAGE
COPY service_to_service.py ./
RUN pip install --upgrade pip && \
pip install requests
CMD ["python3", "service_to_service.py"]
Datei service_to_service_spec.yaml (Dienstspezifikation)¶
Snowflake verwendet die von Ihnen in dieser Spezifikation angegebenen Informationen zur Konfiguration und Ausführung Ihres Dienstes.
spec:
container:
- name: main
image: /tutorial_db/data_schema/tutorial_repository/service_to_service:latest
env:
SERVICE_URL: "http://echo-service:8000/echo"
Diese Spezifikation stellt Informationen für Snowflake zum Konfigurieren und Ausführen Ihres Jobs bereit. Um mit dem Echo-Dienst zu kommunizieren, benötigt der Job Folgendes:
DNS-Name des Echo-Dienstes, an den Anforderungen gesendet werden.
HTTP-Port, der vom Echo-Dienst auf Anforderungen überwacht wird.
HTTP-Pfad, wo der Echo-Dienst die zu sendende Anforderung erwartet.
So erhalten Sie diese Informationen:
Um den DNS-Namen des Echo-Dienstes (Tutorial 1) zu erhalten, führen Sie den SQL-Befehl DESCRIBE SERVICE aus:
DESCRIBE SERVICE echo_service;
Resultierender DNS-Name für den Echo-Dienst:
echo-service.fsvv.svc.spcs.internal
Beachten Sie, dass Sie in diesem Tutorial den Jobdienst in demselben Datenbankschema (
data-schema
) erstellen, in dem auch der Echo-Dienst (Tutorial 1) erstellt wird. Daher benötigen Sie nur den „echo-service“-Teil des obigen DNS-Namens, um den Wert fürSERVICE_URL
zu konstruieren.Rufen Sie die Portnummer (8000), der vom Echo-Dienst auf Anforderungen überwacht wird, aus der Dienstspezifikationsdatei des Echo-Dienstes ab (Tutorial 1). Sie können auch den SQL-Befehl SHOW ENDPOINTS verwenden.
Erstellen Sie dann die obige Spezifikationsdatei (service_to_service_spec.yaml
). Zusätzlich zu den Pflichtfeldern containers.name
und containers.image
fügen Sie auch das optionale Feld containers.env
hinzu, um die vom Dienst verwendeten Umgebungsvariablen anzugeben.
Lokales Erstellen und Testen eines Images¶
Sie können das Docker-Image lokal testen, bevor Sie es in ein Repository Ihres Snowflake-Kontos hochladen. Bei lokalen Tests wird Ihr Container eigenständig ausgeführt (er ist kein Jobdienst, der von Snowflake ausgeführt wird).
Bemerkung
Der für dieses Tutorial bereitgestellte Python-Code verwendet die requests
-Bibliothek, um Anfragen an einen anderen Snowpark Container Services-Dienst zu senden. Wenn Sie diese Bibliothek nicht installiert haben, führen Sie pip aus (zum Beispiel pip3 install requests
).
Führen Sie die folgenden Schritte aus, um das Docker-Image von Tutorial 3 zu testen:
Der Echo-Dienst muss aktiviert sein (Tutorial 1). Zum Starten des Echo-Dienstes aus Tutorial 1 führen Sie in einem Terminalfenster den folgenden Python-Befehl aus:
SERVER_PORT=8000 python3 echo_service.py
Öffnen Sie ein weiteres Terminalfenster, und führen Sie den Python-Code aus, der für dieses Tutorial bereitgestellt wurde:
SERVICE_URL=http://localhost:8000/echo python3 service_to_service.py
Beachten Sie, dass
SERVICE_URL
eine Umgebungsvariable ist. Für lokale Tests müssen Sie für diese Variable explizit einen Wert festlegen. Diese URL entspricht dem Port und dem HTTP-Pfad, die beim Starten des Echo-Dienstes explizit angegeben wurden.Wenn der Jobdienst ausgeführt wird, sendet er eine POST-Anforderung an den Echo-Dienst, der Port 8000 überwacht, mit der Zeichenfolge „Hello“ im Anforderungstext. Der Echo-Dienst gibt die Eingabe als Echo wieder zurück und antwortet mit „I said Hello“ (Ich sagte Hallo).
Beispielantwort:
service-to-service [2023-04-23 22:30:41,278] [INFO] Calling http://localhost:8000/echo with input Hello service-to-service [2023-04-23 22:30:41,287] [INFO] Received response from http://localhost:8000/echo: I said Hello
Überprüfen Sie das Protokoll, um sicherzustellen, dass die Kommunikation zwischen den Diensten erfolgreich war.
Nächste Schritte¶
Tutorial 4: Dienst mit einem eingebundenen Blockspeicher-Volume erstellen