Spouštění úloh pomocí Azure WebJobs
27.11.2021
Slovníček
App Service Web App | Služba určená k hostování webových stránek, která běží v Azure Cloudu (PaaS). |
App Service Plan | Definice výpočetních prostředků, které je možné pro webovou službu vyhradit. Plány se liší cenou i podporou některých funkcí. V jednom plánu může běžet vícero aplikací. |
WebJob | Funkce, která je součástí App Service služby. Umožňuje nám spouštět skripty, které běží buď pořád (continuous jobs) nebo je lze spouštět manuálně pomocí HTTP požadavku nebo můžeme spouštění naplánovat přes CRON scheduler (triggered jobs). |
FTPS | Protokol pro bezpečný přenos dat. App Service Plan FTPS podporuje ve výchozím nastavení, přihlašovací údaje najdeme v záložce Azure portálu "App Service name" > Deployment Center > FTPS credentials. Protokol pak můžeme využít pro nasazení web jobu. |
FileZilla | Populární open-source a cross-platform FTPS klient. První verze byla uvolněna již v roce 2001. |
Obsah
Úvod
WebJob, který budeme nastavovat bude typu continuous, to znamená že nahraný script poběží pořád. Script bude napsaný v Pythonu a vyzkoušíme si pomocí Telethon knihovny odposlouchávat Telegram zprávy. To má hned několik využítí, buď si zprávy můžeme přeposílat do jiné služby a nebo je můžeme pojmout jako příkazy a ovládat tímto způsobem z Telegram aplikace libovolnou službu, disponující API. Obě možnosti mi přijdou super, ale use case samozřejmě může být jiný 🙂 WebJoby mohou běžet pouze na Windows platformě (Linux zatím není podporovaný) a potřebujeme minimálně App Service plán B1.
Příprava služby
Než budeme moci spustit náš script, musíme přidat podporu pro Python runtime do App Service služby a také nastavit podporu pro continuous spouštění. Zároveň odebereme limit pro počet zaznamenaných logů, tím že logy přesměrujeme do blob úložiště.
Přidání podpory pro Python
Python standardně ve službě nainstalovaný není, tak ho musíme přidat. To můžeme provést v Azure portálu v záložce
"App Service name" > Development Tools: Extensions
Nastavení funkce Always On
Ve výchozím stavu pokud na webový server nejde žádný požadavek po dobu 20 minut tak se přepne do nečinného (idle) stavu a náš script by přestal fungovat.
Nastavením funkce Always On, která je mandatorní pro continuous joby a CRON scheduled joby, tomu předejdeme.
Nastavení je v záložce
"App Service name" > Settings: Configuration > General settings
Přesměrování logů do Blob úložiště
Logy si můžeme procházet v SCM dashboardu, do kterého se dostaneme následovně
"App Service name" > WebJobs: "Web Job name" => Logs (přesměrování do SCM dashboardu) > "Web Job Name"
Nicméně množství logů, které se zobrazují je omezené a může se nám zobrazit následující chyba
Nastavení env proměnné
Pokud náš script bude používat nějaké credentials, connection stringy apod. můžeme je nastavit jako tzv. environment proměnné. Výhodou je, že náš kód nebude obsahovat žádné sensitivní údaje, takže ho můžeme zaverzovat a zároveň jsme schopní tyto údaje snadno měnit. Nastavení provedeme v "App Service name" > Settings: Configuration > Application settings. V mém případě to budou přihlašovací údaje do API Telegramu.
Script
Použít můžeme několik jazyků jako je powershell, php, python, javascript, java nebo bash a windows cmd příkazy. Princip je vždy stejný, po nahrání souborů do složky /site/wwwroot/App_Data/jobs/[continuous|triggered]/job_name/job_name se spustí run soubor s podporovanou příponou, například run.py nebo run.bat. run.bat můžeme použít k instalaci závislostí jako jsou python knihovny a až poté teprve spustit náš script. Závislosti stačí nainstalovat pouze jednou, takže po prvním spuštění můžeme run.bat zjednodušit, případně balíčky nainstalovat pomocí Azure console.
Konzoli najdeme v "App Service name" > Development tools: Console a je velmi užitečná i pro mnoho dalších účelů, například zjištění podporované node.js verze apod.
Nicméně zpátky ke scriptu, script naslouchá na příchozí zprávy v námi vybraném Telegram kanálu. To samo o sobě není příliš podstatné, jedná se pouze o ukázku libovolného jobu.
requirements.txt
Soubor obsahující závislosti.
telethon
requests
Soubor, který se spustí jako první, nejdříve zaktualizuje balíčkovacího manažera pip a potom nainstaluje závislosti ze souboru requirements.txt. Cestu k Python.exe souboru zjistíme v Azure portálu v detailu nainstalovaného rozšíření.
D:\home\python364x86\python -m pip install --upgrade pip
D:\home\python364x86\python -m pip install --upgrade -r requirements.txt
D:\home\python364x86\python program.py
Náš hlavní script, který naslouchá na příchozí zprávu a přepošle jí na HTTP adresu s parametrem message. Credentials načítáme z env proměnných z os.environ pole.
import os
import requests
from telethon import TelegramClient, events
print("Program started.", flush=True)
# define variables
api_id = os.environ['Telegram_api_id']
api_hash = os.environ['Telegram_api_hash']
channel = '@some_channel'
webhook = 'some url'
# prepare client
client = TelegramClient('session', api_id, api_hash)
# prepare incoming handler
@client.on(events.NewMessage(chats=channel))
async def my_event_handler(event):
requests.get(url = webhook, params = {'message': event.text})
# start
client.start()
print("Listening...", flush=True)
# end
client.run_until_disconnected()
print("Program ended.", flush=True)
Deployment
Pokud máme vytvořený script, můžeme ho nasadit jako web job. Nasazení probíhá dvojím způsobem. Nejdříve při vytváření jobu musíme nahrát scripty zabalené jako .zip soubor a poté můžeme scripty přehrávat pomocí FTPS klienta. V "App Service name" > Settings: Web Jobs > Add nahrajeme naše soubory pomocí jednoduchého formuláře.
Závěr
V tomto článku jsme si nastavili program, který nám běží na pozadí webového serveru. Alternativou může být použití standardní webové aplikace nebo Azure funkce a úlohu spouštět pomocí HTTP požadavku. Doufám, že článek byl alespoň trochu srozumitelný a těším se na příště 😎