/ Azure

Azure Functions - Teil 1

Die in der Build 2016 Konferenz vorgestellten Azure Functions beschäftigen mich. Sie sind zur Zeit noch im Preview Stadium. Ich finde sie sehr praktisch und einfach einzusetzen.
Microsoft gibt offen zu, dass Azure Functions ähnlich Amazons AWS Lambda sind, doch ich verfolge Amazon Web Services nur mehr sehr am Rande und daher kannte ich diese nicht.

Im Rahmen meiner Let's Code Serie auf YouTube, will ich Azure Functions einsetzen.

Wo sich die Azure Functions in Azure eingliedern lassen und was das eigentlich ist, will ich in diesem Artikel zeigen. Auch ein paar Tipps, wie und wo man am besten startet, sollen nicht fehlen.

Dieser Artikel ist Teil der Serie:
Let's Code Artikel

Get started with Azure Functions


1. Azure Functions - Eingliederung

Cloud Services

Azure, Microsofts Cloud Strategie, startete mit den Cloud Services (als Web oder Worker Role). Zum Speichern von Daten gab es die Azure SQL Services und Azure Storage mit Tables, Queues und Blobs. Später bot Microsoft dann auch virtuelle Maschinen an.
Auch ein Cloud Service läuft in einer virtuellen Maschine, wobei die Worker Role den IIS nicht automatisch aktiviert hat.
Bei Cloud Services muss man sich um das Betriebssystem und den IIS nicht mehr kümmern, es wird von Microsoft gewartet.
Darauf aufbauend entwickelten sich einzelne Komponenten, wie Mobile Services und Web Sites, die das Ziel hatten, die virtuelle Maschine darunter, noch mehr zu verstecken.
Auch statt der Worker Role, für Background Tasks, gibt es eine vereinfachte Variante, sogenannte WebJobs.

Der Vorteil dieser Ebene ist, dass man die Umgebung noch mehr standardisieren kann und daher einfacher skalieren kann.

App Services

Schließlich bündelte man diese Services wieder in die sogenannten Azure App Services.
Dort enthalten sind zur Zeit:

  • Web-Apps
  • Mobile-Apps
  • Logik-Apps
  • API-Apps
WebJobs

Auch die Azure Functions passen am ehesten zu den App Services.
In der Dokumentation und im Portal sieht man dass die Azure Functions gebündelt als Function Apps genannt werden, also eine Gruppe von Azure Functions. Die Azure Function Implementierung ist Open Source und dort heißt das Projekt azure-webjobs-sdk-script.

Die Azure Functions sind also zum einen mal eine Erweiterung der WebJobs.

Sie sind aber noch eine Abstraktionsebene darüber. Dazu muss ich ein wenig ausholen.

Azure App Services benötigen im allgemeinen einen Service Plan, das ist eine Komponente, die man sich beim Erstellen auswählen muss und zwar geht es hier darum, wie die virtuelle Maschine darunter aussieht. Ob man eine für sich alleine verwendet, oder ob man sie mit anderen Kunden teilt. Damit ist der Preis festgelegt und auch welche Features möglich sind, z.B. wieviele WebApps man in diesem Service Plan laufen lassen kann, ob man SSL verwenden kann oder ob man eine eigene Domäne konfigurieren kann.

Es gibt auch einen free und einen shared ServicePlan. Bei diesem Kontingent hat man keine dezidierte virtuelle Maschine hinter sich, sondern man teilt sich diese mit anderen Kunden und wenn ein Request kommt, dann wird unser Code in einen vorbereiteten App Pool geladen und angesprochen. Nach einer bestimmten Zeit wird das Service wieder entladen. Im Gegensatz zu den anderen Service Plänen Basic und Standard kann man das Entladen nicht weg konfigurieren und deshalb dauert der erste Request oft lange. (Dem ein Schnippchen zu schlagen, darum geht es ja in meiner Let's Code Beispielanwendung.)

ServicePlan: dynamic

Azure Functions kann man nun und das ist ganz neu, in einem dynamischen ServicePlan betreiben. (Es wäre auch möglich sie in einem klassischen ServicePlan zu betreiben.)
Die technische Umsetzung ist sicher sehr ähnlich dem shared Service Plan, dass einfach Laufzeitumgebungen bereitstehen und diese bei einem Request befüllt und abgearbeitet werden.
Der virtuelle Server wird hier im Gegensatz dazu, aber sofort wieder freigegeben. Das kann man ganz gut aus der angekündigten Abrechnung dafür rauslesen. Es wird auf 100ms verbrauchter Rechenleistung gerundet (mindestens aber 100ms, wenn ich das richtig gesehen habe), wobei die Kosten dafür vom gewählten Memoryverbrauch abhängen.

Der dynamische ServicePlan hat nun den großen Vorteil, dass man sich keine Gedanken mehr machen muss, wie man das Projekt am besten in die virtuellen Maschinen einpassen kann. Im Prinzip war das auch bei den shared und free ServicePlänen der Fall, aber diese sind doch nur sehr eingeschränkt nutzbar (bei shared z.B. ist nur 4 h CPU Dauer am Tag maximal inkludiert).
Hier jedoch kann man das ganz groß skalieren und das ist der eine große Vorteil und der zweite ist, die einfache Entwicklung. Dazu später mehr.

2. Azure Functions - Was ist das nun?

Man schreibt eine Funktion (bevorzugt in C# oder JavaScript) und diese wird durch einen Trigger aufgerufen.
Wobei ein Trigger

  • ein Timer sein kann,
  • ein Event in ausgewählten Azure Ressourcen (neuen Eintrag in Queue, Blobstorage oder ServiceBusQueue/Topic) oder
  • ein Http Request (auch WebHooks werden unterstützt)

Man kann über nuget bzw. npm Bibliotheken dazu laden.

Http Trigger unterstützt auch OAuth zu Azure Active Directory (AAD) und diversen anderen Anbietern (Google, Facebook, ...).

Den Source kann man im Portal entwickeln oder Continuous Integration einrichten (GitHub z.B.), so wie auch in den anderen Azure Services.

Um sich Code für den Zugriff auf In und Output Parameter zu ersparen, wird auch angeboten, diese per Konfiguration zur Verfügung zu stellen. (praktisch z.B. für HTTP Requests)

Jede Azure Function ist immer auch mit einem Azure Storage verbunden. Dies muss man beim Einrichten einstellen (Es muss kein Neuer sein.). Dort werden die Logfiles abgelegt. Diesen Storage kann man auch ganz einfach ansprechen, indem man dafür In- und Outputs definiert.

3. Generieren

Das Erstellen einer Azure Function lernt man am besten direkt auf der Dokumentationsseite.

Ich habe dazu auch ein Let's Code Video erstellt:

Let's Code [011]: Azure Functions - KeepAlive[3]
Ein paar Tipps dazu:

Will man das Projekt etwas strukturierter aufbauen mit definierter Ressourcengruppe, empfiehlt es sich den Link zum Portal zu verwenden:
Or create a function app from Azure Portal.
(findet man ganz unten auf Azure Functions-Portal)

Leider scheint es einen Bug im Portal zu geben (kann auch ein Bedienungsfehler von mir sein), oft verschwindet die Auswahl des dynamischen Service Plans, sobald ich die Ressourcengroup auswähle und man kann dann nur mehr einen klassischen ServicePlan auswählen.
Ich habe mit Refresh der Seite (F5) das Problem beheben können oder mal direkt von der Ressourcegruppe ausgehend und Add "Function App". Notfalls erzeugt man eine neue Ressourcegroup. Ich habe auch das Gefühl, dass es besser ist, wenn die Ressourcegroup in der Region USA West ist. - Naja, wird sich bestimmt bald lösen.

So sollte dies aussehen:
Portal - Add Azure Function

Eine Function App kann nun mehrere Azure Functions enthalten.

Es empfiehlt sich, die Azure Functions wirklich mit dem Portal anzulegen und auch die Trigger und In- / Outputs festzulegen. Dadurch muss man nicht das json File händisch erstellen. (Man sieht dieses Konfigurationsfile auch, wenn man auf advanced editor im Integrate tab klickt.)

Man kann im Portal auch den Sourcecode der Funktion editieren, es ist jedoch bestimmt einfacher, wenn man das Projekt lokal bearbeitet und dann hochlädt.
Azure Functions sind schon so gedacht, dass man wenig Code schreibt und daher macht diese Funktion im Portal durchaus Sinn. Doch man stößt im Moment sehr schnell an die Grenzen, schließlich will man den Code in einem Sourcecode Repository sichern, Bibliotheken verwenden, TypeScript verwenden, ...
Dieses Thema will ich in einem zweiten Teil behandeln.
Azure Functions - Teil 2

4. Meinung

Das geniale an Azure Functions finde ich den dynamischen ServicePlan. Dadurch ist es endlich möglich Funktionalität in der Azure Cloud sehr einfach bereitzustellen, ohne dass man quasi eine virtuelle Maschine bezahlen muss (Das ist ja auch bei Cloud Services oder App Services mit Basic oder Standard Service Plan so.) und trotzdem eine stabile, performante, skalierbare Möglichkeit zu haben.
Aus diesem Grund, war mir die Eingliederung in das Azure Gefüge in diesem Artikel sehr wichtig.

Natürlich muss man trotzdem die Kosten im Auge behalten und es kann auch sein, dass es sich irgendwann auszahlt, dann doch die Azure Functions an eigene Maschinen zu binden. Aber das ist schließlich möglich und dadurch ist man in keiner Sackgasse gelandet.

Azure Functions stellen sich für mich als leichtgewichtige Cloud Services oder WebJobs dar, wobei sich das erst zeigen muss. Ich kann mir durchaus auch komplexere Jobs vorstellen. Für größere Tasks sind grundsätzlich aber eher Docker Container oder Micro Services (Azure Service Fabric) gedacht. Statt Timerjobs gibt es auch mehrere Varianten: Azure Scheduler (in Kombination mit Cloud Services oder WebJobs) oder Azure Batch für stark skalierbare, rechenintensive Tasks. Die haben sicher nach wie vor ihre Daseinsberechtigung.

Irgendwie ist es in letzter Zeit immer komplexer geworden in Azure und mit Azure Functions habe ich das Gefühl, es wird einfacher.

Kann durchaus sein, dass ich noch Nachteile dieses Azure Functions Konzepts nicht sehe, vielleicht stoße ich bei meinen Tests darauf. Auf alle Fälle bin ich neugierig, wie sich Azure Functions weiter entwickeln.


Artikel in diesem Blog


Weitere Let's Code Artikel.