Autoriser l'exécution rapide des scripts Python dans Cloud Run à l'aide du répondeur

Résumé

Cloud Run a été diffusé en GA. Je voulais essayer un script python qui s'exécutait en local et prenait un peu de temps à s'exécuter dans Cloud Run. Les conteneurs exécutés dans Cloud Run doivent pouvoir recevoir et exécuter des requêtes via HTTP. Cloud Run doit également prendre en compte les délais d'expiration des demandes. Je vais vous présenter le répondeur car il était facile d'exécuter le script rapidement sans tenir compte du délai d'expiration de la requête.

Histoire de prémisse

Environnement éprouvé

responder

le cadre de service HTTP de python. Puisqu'il implémente ASGI (Asynchronous Server Gateway Interface), il peut également effectuer un traitement asynchrone comme l'indique le nom Asynchronous. Le traitement asynchrone lui-même peut être effectué avec d'autres frameworks. Cependant, lorsque j'ai jeté un coup d'œil rapide à Flask et Django, qui sont célèbres pour le framework python, j'ai dû installer des packages supplémentaires et modifier le fichier de configuration. En regardant l'exemple de code du répondeur, il semblait facile à installer et à implémenter, j'ai donc essayé de l'utiliser.

Ce que j'ai fait

À propos de la structure des répertoires et de chaque fichier

vaivailx@MacBook-Pro-2 responder_sample_for_cloudrun % tree -L 3 .
.
├── Dockerfile
├── requirements.txt
└── src
    ├── sample.py
    └── webapp.py

Chaque fichier python effectue les opérations suivantes:

C'est tout le fichier requirements.txt.

responder==2.0.4

Dans le Dockerfile, mettez à jour le package avec apt et installez le package décrit dans requirements.txt.

FROM python:3.7.5-buster

ENV APP_HOME /app
WORKDIR $APP_HOME
ADD ./requirements.txt /app
ADD ./src /app

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
    && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
    # Install pylint
    && pip --disable-pip-version-check --no-cache-dir install pylint \
    # Update Python environment based on requirements.txt
    && pip --disable-pip-version-check --no-cache-dir install -r requirements.txt \
    && rm -rf requirements.txt \
    # Clean up
    && apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*

# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=

# run app
ENV PORT '8080'
CMD python3 webapp.py
EXPOSE 8080

Traitement pour accepter les requêtes HTTP à l'aide du répondeur. Préfixez simplement def avec ʻasync` et la fonction sera asynchrone.

webapp.py

import logging

import responder

from sample import process_sample

logging.basicConfig(filename=f'/var/log/webapp.log', level=logging.DEBUG)

api = responder.API()

@api.route("/async")
async def asyncsample(req, resp):

    @api.background.task
    def process_param(params):
        t = int(params.get('time', 10))
        process_sample(t)

    process_param(req.params)
    resp.media = {'async success': True}

@api.route("/sync")
def syncsample(req, resp):

    t = int(req.params.get('time', 10))
    process_sample(t)
    resp.media = {'sync success': True}

if __name__ == '__main__':
    api.run()

Le journal est généré car il peut être confirmé au moment de l'exécution avec Croud Run. Comme le nom de la route l'indique, accéder au chemin racine / asynchrone exécutera un traitement asynchrone, et accéder au chemin racine / sync exécutera le traitement de motivation. Cette fois, j'ai essayé de dormir pour la valeur du paramètre de requête.

sample.py

import time
import logging

def process_sample(secs):
    logging.debug('process starts.')
    time.sleep(secs)
    logging.debug('process ends.')

Confirmation du résultat de l'exécution dans Cloud Run

Maintenant, définissons le délai d'expiration de la requête Cloud Run sur 30 secondes et exécutons-le. (Comme attendre 5 minutes est gênant, je l'ai changé par rapport à la valeur par défaut.)

** Exécution synchrone: temps d'exécution 10 secondes **

vaivailx@cloudshell:~ (cloudrun-test-259804)$ date;curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://responderasync-jpwo3ltkhq-an.a.run.app/sync?time=10
Fri Dec 13 09:52:59 +09 2019
{"sync success": true}vaivailx@cloudshell:~ (cloudrun-test-259804)$
sync10_result.png

→ Terminé normalement

** Exécution synchrone: temps d'exécution 40 secondes **

vaivailx@cloudshell:~ (cloudrun-test-259804)$ date;curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://responderasync-jpwo3ltkhq-an.a.run.
app/sync?time=40
Fri Dec 13 09:55:45 +09 2019
upstream request timeoutvaivailx@cloudshell:~ (cloudrun-test-259804)$
sync40_result.png

→ Délai d'expiration

** Exécution asynchrone: temps d'exécution 10 secondes **

vaivailx@cloudshell:~ (cloudrun-test-259804)$ date;curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://responderasync-jpwo3ltkhq-an.a.run.app/async?time=10
Fri Dec 13 10:02:31 +09 2019
{"async success": true}vaivailx@cloudshell:~ (cloudrun-test-259804)$
async10_result.png

→ Terminé normalement

** Exécution asynchrone: temps d'exécution 40 secondes **

vaivailx@cloudshell:~ (cloudrun-test-259804)$ date;curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://responderasync-jpwo3ltkhq-an.a.run.app/async?time=40
Fri Dec 13 10:03:57 +09 2019
{"async success": true}vaivailx@cloudshell:~ (cloudrun-test-259804)$
async40_result.png

→ Terminé normalement

Ce que j'ai confirmé en passant

À propos, le délai d'expiration de la requête HTTP était jusqu'à 900 secondes sur l'écran de réglage, mais ce n'est pas le temps d'exécution C'est le temps qu'il faut pour recevoir une demande et renvoyer une réponse, et j'ai pu confirmer que cela peut être fait pendant 900 secondes ou plus s'il est rendu asynchrone. Ce qui suit est le résultat d'une exécution asynchrone pendant 1 200 secondes.

async1200_result.png

finalement

Recommended Posts

Autoriser l'exécution rapide des scripts Python dans Cloud Run à l'aide du répondeur
Comment installer OpenCV sur Cloud9 et l'exécuter en Python
Obtenir l'équilibre Suica en Python (en utilisant libpafe)
Connectez-vous à Slack à l'aide de requêtes en Python
Comment obtenir stacktrace en python
Obtenez des données Youtube en Python à l'aide de l'API Youtube Data
Comment changer de version de Python dans cloud9
Obtenez Cloud Logging disponible en Python en 10 minutes
Comment obtenir la valeur du magasin de paramètres dans lambda (en utilisant python)
Obtenir l'URL de l'image à l'aide de l'API Flickr en Python
Comment obtenir les fichiers dans le dossier [Python]
Comment exécuter LeapMotion avec Python non-Apple
Que faire pour obtenir une feuille de calcul Google en Python
Utilisez os.getenv pour obtenir des variables d'environnement en Python
Que faire si vous obtenez «Python non configuré». Utilisation de PyDev dans Eclipse
Obtenir la date en Python
Tutoriel Cloud Run (python)
Profilage rapide des scripts Python
Comment obtenir le nom de la variable lui-même en python
Comment obtenir le nombre de chiffres en Python
Comment exécuter python dans l'espace virtuel (pour MacOS)
Comment exécuter des tests avec Python unittest
Créer un plugin pour exécuter Python Doctest sur Vim (2)
Obtenez des données LEAD à l'aide de l'API REST de Marketo en Python
Un mémorandum pour exécuter un script python dans un fichier bat
Comment exécuter setUp une seule fois dans Python Unittest
Comment quitter lors de l'utilisation de Python dans Terminal (Mac)
Comment récupérer plusieurs tableaux à l'aide de slice en python.
Comment exécuter une commande à l'aide d'un sous-processus en Python
Obtenez des commentaires YouTube en Python
Essayez de le faire avec GUI, PyQt en Python
Pour vider stdout en Python
Obtenez le mois dernier en Python
Exécuter des tâches automatisées en Python
Importer dynamiquement des scripts en Python
Exécuter des commandes shell en Python
Exécuter Python unittest en parallèle
Connectez-vous au site Web en Python
Utilisation de verticalenv dans les scripts shell
Publier sur Twitter en utilisant Python
Développer une bibliothèque pour obtenir la liste des collections Kindle en Python
[OCI] Script Python pour obtenir l'adresse IP d'une instance de calcul dans Cloud Shell
Commencez à Selenium en utilisant python
[Question] Comment obtenir les données des données textarea en temps réel à l'aide du flacon du framework Web Python
J'ai essayé "Comment obtenir une méthode décorée en Python"
Exécutez LINE Bot implémenté en Python (Flask) "sans utiliser Heroku"
Obtenir la taille du terminal en Python
Pour renvoyer char * dans une fonction de rappel à l'aide de ctypes en Python
Obtenir explicitement EOF en python
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Comment obtenir une liste d'exceptions intégrées pour python
Comment exécuter Notepad ++ Python
Appuyez sur REST en Python pour obtenir des données de New Relic
Précautions lors de l'utilisation de Python avec AtCoder
J'ai fait un chronomètre en utilisant tkinter avec python
Scripts pouvant être utilisés lors de l'utilisation de Bottle en Python
Comment développer en Python
Obtenez des notes Evernote en Python
Choses à garder à l'esprit lors de l'utilisation de cgi avec python.
Je veux pouvoir exécuter Python avec VS Code