Tutoriel 3 : communications de service à service¶
Introduction¶
Dans ce tutoriel, vous créez un service de tâche Snowpark Container Services qui communique avec le service echo que vous avez créé dans le tutoriel 1. Lorsque le service de tâche s’exécute, il envoie une requête POST à l’URL de service echo (que vous avez fournie dans la spécification du service) avec une chaîne « Hello » dans le corps de la requête. Le service echo renvoie une réponse contenant la chaîne « Bob said Hello » dans le corps de la réponse. Vous accédez aux journaux du conteneur de services de tâches pour vérifier que les communications ont réussi.
Ce tutoriel comporte deux parties :
Partie 1 : créez et testez un service de tâche. Vous téléchargez le code fourni pour ce tutoriel et suivez les instructions étape par étape :
Téléchargez le code de service de tâche pour ce tutoriel.
Créez une image Docker pour Snowpark Container Services, et chargez l’image dans un référentiel de votre compte.
Mettez en zone de préparation le fichier de spécification, qui donne à Snowflake les informations de configuration du conteneur. En plus du nom de l’image à utiliser pour démarrer un conteneur, la spécification définit la variable d’environnement (
SERVICE_URL
) sur l’URL de service echo. Le code de l’application lit cette variable d’environnement pour envoyer des demandes au service echo.Exécutez le service de tâche. En utilisant la commande EXECUTE JOB SERVICE, vous pouvez exécuter le service de tâche en fournissant le fichier de spécification et le pool de calcul où Snowflake peut exécuter le conteneur. Enfin, accédez aux journaux du conteneur de service de tâches pour vérifier que la communication entre le service de tâche et le service s’est déroulée correctement.
Partie 2 : comprendre le code du service de tâche. Cette section donne une vue d’ensemble du code de service et met en évidence la façon dont les différentes composantes collaborent.
Conditions préalables¶
Effectuez le tutoriel 1 et vérifiez que le service echo fonctionne.
SELECT SYSTEM$GET_SERVICE_STATUS('echo_service', 10);
1 : Télécharger le code de service¶
Un code (une application Python) est fourni pour créer un service de tâche.
Téléchargez
SnowparkContainerServices-Tutorials.zip
.Décompressez le contenu, qui comprend un répertoire pour chaque tutoriel. Le répertoire
Tutorial-3
contient les fichiers suivants :service_to_service.py
Dockerfile
service_to_service_spec.yaml
2 : Construire et charger une image¶
Construisez une image pour la plateforme linux/amd64 prise en charge par Snowpark Container Services, puis chargez l’image dans le référentiel d’images de votre compte (voir Configuration commune).
Vous aurez besoin d’informations sur le référentiel (l’URL du référentiel et le nom d’hôte du registre) avant de pouvoir construire et charger l’image. Pour plus d’informations, voir Registre et référentiels.
Obtenir des informations sur le référentiel
Pour obtenir l’URL du référentiel, exécutez la commande SQL SHOW IMAGE REPOSITORIES.
SHOW IMAGE REPOSITORIES;
La colonne
repository_url
de la sortie fournit l’URL. En voici un exemple :<orgname>-<acctname>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository
Le nom d’hôte dans l’URL du référentiel est le nom d’hôte du registre. En voici un exemple :
<orgname>-<acctname>.registry.snowflakecomputing.com
Construire l’image et la charger dans le référentiel
Ouvrez une fenêtre de terminal et accédez au répertoire contenant les fichiers que vous avez décompressés.
Pour créer une image Docker, exécutez la commande
docker build
suivante à l’aide de la CLI Docker. Notez que la commande spécifie le répertoire de travail actuel (.) commePATH
pour les fichiers à utiliser pour la construction de l’image.docker build --rm --platform linux/amd64 -t <repository_url>/<image_name> .
Pour
image_name
, utilisezservice_to_service:latest
.
Exemple
docker build --rm --platform linux/amd64 -t myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/service_to_service:latest .
Chargez l’image dans le référentiel de votre compte Snowflake. Pour que Docker puisse charger une image en votre nom dans votre référentiel, vous devez d’abord authentifier Docker avec le registre.
Pour authentifier Docker auprès du registre Snowflake, exécutez la commande suivante.
docker login <registry_hostname> -u <username>
Pour
username
, indiquez votre nom d’utilisateur Snowflake. Docker vous demandera votre mot de passe.
Pour charger l’image, exécutez la commande suivante :
docker push <repository_url>/<image_name>
Exemple
docker push myorg-myacct.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/service_to_service:latest
3 : Mettre en zone de préparation le fichier de spécification¶
Pour charger votre fichier de spécification de service (
service_to_service_spec.yaml
) sur la zone de préparation, utilisez l’une des options suivantes :L’interface Web de Snowsight. Pour obtenir des instructions, voir Sélection d’une zone de préparation interne pour les fichiers locaux.
La CLI SnowSQL. Exécutez la commande PUT suivante :
PUT file://<absolute-path-to-spec.yaml> @tutorial_stage AUTO_COMPRESS=FALSE OVERWRITE=TRUE;
La commande définit OVERWRITE=TRUE afin que vous puissiez charger le fichier à nouveau, si nécessaire (par exemple, si vous avez corrigé une erreur dans votre fichier de spécification). Si la commande PUT est exécutée avec succès, les informations relatives au fichier chargé sont affichées.
4 : Exécutez le service de tâche¶
Vous êtes maintenant prêt à tester le service de tâche Snowflake que vous avez créé. Lorsque le service de tâche est exécuté, Snowflake collecte tout ce que votre code dans le conteneur envoie à la sortie standard ou à l’erreur standard en tant que journaux. Vous pouvez utiliser la fonction système SYSTEM$GET_SERVICE_LOGS
pour accéder aux journaux. Pour plus d’informations, voir Snowpark Container Services : considérations supplémentaires pour les services.
Pour démarrer un service de tâche, exécutez la commande EXECUTE JOBSERVICE :
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';
Remarques :
FROM et SPEC indiquent le nom de la zone de préparation et le nom du fichier de spécification du service.
COMPUTE_POOL fournit les ressources de calcul où Snowflake exécute le service de tâche.
Snowflake exécute le conteneur identifié dans le fichier de spécification. Le conteneur lit la valeur de la variable d’environnement
SERVICE_URL
(http://echo-service:8000/echo
) et envoie une requête au service echo sur le port 8000 au chemin HTTP/echo
.Snowflake démarre le service de tâche et renvoie le résultat suivant :
+------------------------------------------------------------------------+ | status | |------------------------------------------------------------------------| | Job TUTORIAL3_JOB_SERVICE completed successfully with status: DONE | +------------------------------------------------------------------------+
Notez que la réponse comprend le nom du service de tâche.
(facultatif) Une fois le service de tâche terminé, vous pouvez obtenir plus d’informations au sujet de son exécution. Ceci est utile pour déboguer l’échec du service de tâche. Pour obtenir le statut du service de tâche, appelez la fonction SYSTEM$GET_SERVICE_STATUS — Obsolète :
CALL SYSTEM$GET_SERVICE_STATUS('TUTORIAL3_JOB_SERVICE');
Exemple de sortie :
[ { "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" } ]
Pour consulter les journaux des services de tâche, appelez SYSTEM$GET_SERVICE_LOGS :
CALL SYSTEM$GET_SERVICE_LOGS('tutorial_3_job_service', 0, 'main');
main
est le nom du conteneur à partir duquel vous récupérez le journal. Vous définissez ce nom de conteneur pour le conteneur dans le fichier de spécification du service.Exemple de journal :
+--------------------------------------------------------------------------------------------------------------------------+ | 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 : Nettoyage¶
Snowflake facture les nœuds du pool de calcul qui sont actifs pour votre compte. (Voir Utilisation des pools de calcul). Pour éviter les frais non voulus, arrêtez d’abord tous les services en cours d’exécution sur un pool de calcul. Ensuite, suspendez le pool de calcul (si vous avez l’intention de le réutiliser plus tard) ou supprimez-le.
Arrêtez tous les services et tous les services de tâches sur le pool de calcul.
ALTER COMPUTE POOL tutorial_compute_pool STOP ALL;
Supprimez le pool de calcul.
DROP COMPUTE POOL tutorial_compute_pool;
Vous pouvez également nettoyer le registre des images (supprimer toutes les images) et la zone de préparation interne (supprimer les spécifications).
DROP IMAGE REPOSITORY tutorial_repository;
DROP STAGE tutorial_stage;
6 : Révisez le code du service de tâche¶
Cette section couvre les sujets suivants :
Vérification des fichiers fournis : examinez les différents fichiers de code qui mettent en œuvre le service de tâche.
Construire et tester une image localement. Découvrez comment tester localement l’image Docker avant de la charger vers un référentiel dans votre compte Snowflake.
Vérification des fichiers fournis¶
Le fichier zip que vous avez téléchargé comprend les fichiers suivants :
service_to_service.py
Dockerfile
service_to_service_spec.yaml
Cette section donne un aperçu de la manière dont le code met en œuvre le service de tâche.
Fichier 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)
Lorsque le service de tâche s’exécute :
Snowflake utilise la valeur fournie dans le fichier de spécification pour définir la variable d’environnement SERVICE_URL dans le conteneur.
Le code lit la variable d’environnement.
SERVICE_URL = os.getenv('SERVICE_URL', 'http://localhost:8080/echo').
La fonction
call_service()
utilise la fonctionSERVICE_URL
pour communiquer avec le service echo.
Dockerfile¶
Ce fichier contient toutes les commandes pour construire une image en utilisant Docker.
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"]
fichier service_to_service_spec.yaml (spécification de service)¶
Snowflake utilise les informations que vous fournissez dans cette spécification pour configurer et faire fonctionner votre service.
spec:
container:
- name: main
image: /tutorial_db/data_schema/tutorial_repository/service_to_service:latest
env:
SERVICE_URL: "http://echo-service:8000/echo"
Cette spécification fournit des informations à Snowflake pour la configuration et l’exécution de votre tâche. Pour communiquer avec le service echo, la tâche a besoin des éléments suivants :
Nom DNS du service echo auquel envoyer les requêtes.
Port HTTP sur lequel le service echo écoute.
Chemin HTTP où le service echo s’attend à ce que la requête soit envoyée.
Pour obtenir ces informations :
Pour obtenir le nom DNS du service echo (tutoriel 1), exécutez la commande DESCRIBE SERVICE SQL :
DESCRIBE SERVICE echo_service;
Nom DNS résultant pour le service echo :
echo-service.fsvv.svc.spcs.internal
Notez que, dans ce tutoriel, vous créez le service de tâche dans le même schéma de base de données (
data-schema
) où le service echo (tutoriel 1) est créé. Par conséquent, vous n’avez besoin que de la partie « echo-service » du nom DNS précédent pour construire laSERVICE_URL
.Obtenez le numéro de port (8000) où le service echo écoute à partir du fichier de spécification de service echo (tutoriel 1). Vous pouvez également utiliser la commande SHOW ENDPOINTS SQL.
Vous créez ensuite le fichier de spécification précédent (service_to_service_spec.yaml
). Outre les champs obligatoires containers.name
et containers.image
, vous incluez également le champ containers.env
facultatif pour spécifier des variables d’environnement utilisées par le service.
Construire et tester une image localement¶
Vous pouvez tester l’image Docker localement avant de la charger vers un référentiel dans votre compte Snowflake. Dans les tests locaux, votre conteneur fonctionne de manière autonome (il ne s’agit pas d’un service de tâche exécuté par Snowflake).
Note
Le code Python fourni pour ce tutoriel utilise la bibliothèque requests
pour envoyer des requêtes à un autre service Snowpark Containers. Si cette bibliothèque n’est pas installée, lancez pip (par exemple, pip3 install requests
).
Suivez les étapes suivantes pour tester l’image Docker du tutoriel 3 :
Il faut que le service echo fonctionne (tutoriel 1). Pour démarrer le service echo du tutoriel 1, dans une fenêtre de terminal, exécutez la commande Python suivante :
SERVER_PORT=8000 python3 echo_service.py
Ouvrez une autre fenêtre de terminal et exécutez le code Python fourni pour ce tutoriel :
SERVICE_URL=http://localhost:8000/echo python3 service_to_service.py
Notez que la
SERVICE_URL
est une variable d’environnement. Pour les tests locaux, vous devez définir explicitement cette variable. Cette URL correspond au port et au chemin HTTP explicitement spécifiés lorsque vous avez démarré le service echo.Lorsque la tâche est exécutée, elle envoie une requête POST au service echo écoutant sur le port 8000 avec la chaîne « Hello » dans le corps de la requête. Le service echo renvoie l’écho de l’entrée et renvoie une réponse, « I said Hello ».
Exemple de réponse :
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
Examinez le journal pour vérifier que la communication de service à service a réussi.
Quelle est la prochaine étape ?¶
Tutoriel 4 : créer un service avec un volume de stockage en bloc monté