Azure messaging: een helicopter view? Wanneer wat best gebruiken?

Frederik Vannieuwenborg
Aptus
Published in
7 min readMay 4, 2020

--

Bij het opstellen van een architectuur op Azure gaan we zoveel mogelijk gebruik gaan maken van serverless code. Het doel is om je serverless functions te gaan opsplitsen in logische blokken of distributed architecture. Logische blokken die niet schaden aan het single responsiblity principle. Single responsiblity principle slaat op het feit dat de functie een duidelijke taak heeft en niet te veel verantwoordelijkheid op zich neemt.

De uitdaging in het uitwerken van een distributed architecture is om ervoor te zorgen dat je niet te veel of te weinig componenten hebt. Er bestaat hier geen gouden regel voor en in mijn ervaring is dit vooral aanvoelen en gewoon doen.

Een belangrijke component in een gedistribueerde architectuur is de communicatie tussen de verschillende componenten of hoe de verschillende componenten tegen elkaar spreken. Er zijn hier tal van mogelijkheden voor zoals HTTP, gRPC, AMQP, MQTT, …

Azure biedt ook tal van mogelijkheden aan om dit te realiseren. Die zijn Storage Queues, Service Bus, Event Hub, IoT Hub en Event Grid.

Hieronder geef ik een overzicht van de verschillende opties en hun functionaliteit high-level.

Storage Queues

Storage Queues zijn onderdeel van de Azure Storage infrastructuur. Queues zijn vooral ontworpen voor de ontkoppeling in een applicatie van zaken die asynchroon mogen uitgevoerd worden zoals logging, uitvoeren van een workflow, herschalen van een image, … Zowel de producer als de consumper spreken tegen de REST API (https://docs.microsoft.com/en-us/rest/api/storageservices/Queue-Service-REST-API).

Dit kan via de SDK of rechtstreeks. Dit wil ook zeggen dat de consumer altijd via polling werkt.

De berichten worden meestal volgens het first-in-first-out (FIFO) principe gepubliceerd maar dit is niet gegarandeerd.

Het is mogelijk om meerdere producers te hebben die een bericht op de queue plaatsen waarvan de producer na publiceren een ACK krijgt van de API.

Storage Queues hebben geen ondersteuning voor Optimistic of Pessimistic Concurrency (https://agirlamonggeeks.com/2017/02/23/optimistic-concurrency-vs-pessimistic-concurrency-short-comparison/). Bij het ophalen van een bericht wordt het bericht voor X-tijd onzichtbaar voor de andere consumers. Het is de verantwoordelijkheid van de consumer om het bericht te verwijderen van de queue nadat dat de verwerking gebeurd is.

De maximale grootte van een bericht is 64 KB en de queue kan gigabytes aan berichten bevatten.

Service Bus

Service Bus is zowat de grote broer van Storage Queues en is een enterprise service bus. Naast het ondersteunen van queues is het ook mogelijk om met topics te werken.

Als producer kan je naast het bericht dat je op de bus plaatst ook metadata of headers toevoegen aan een bericht. De consumer kan dan luisteren op de queue naar deze bepaalde header en hiervan de berichten ontvangen.

Daarnaast biedt Service Bus de garantie dat er geen berichten verloren gaan en de volgorde van de berichten in de queue worden gerespecteerd.

Hieronder een overzicht van de vele features die Service Bus biedt met een korte omschrijving erbij:

  • Scheduled delivery Het bericht op de queue wordt maar pas zichtbaar voor de consumers na de ingestelde tijd
  • Message TTL Op een bericht kan je een time-to-live instellen. Wordt het bericht na deze periode niet opgepikt dan wordt het verwijderd uit de queue
  • ForwardTo Je kan een regel instellen op de queue waardoor je op basis van de header een bericht kunt doorsturen naar een andere queue
  • Defer De consumer kan een bericht dat hij op dit moment niet kan verwerken terug plaatsen op de queue en ervoor zorgen dat het pas na X-tijd terug zichtbaar is
  • Sessions Hiermee is het mogelijk om ervoor te zorgen dat bij elkaarhorende berichten na elkaar verwerkt worden
  • Batching Het is mogelijk om meerdere berichten in één keer op de queue te plaatsen
  • Auto-delete queue on idle Wanneer de queue leeg is wordt automatisch iets verwijderd na X-tijd
  • OnMessage Wanneer er een message op een queue komt, wordt er het OnMessage event getriggerd en dit kunnen de consumers dan gebruiken om long-polling te gaan toepassen
  • Duplication detection Een bericht met dezelfde properties en hetzelfde timeframe wordt verwijderd
  • Actions Iets doen met een bericht en doorsturen naar een andere queue of een header toevoegen
  • Transactions Een transactie groepeert twee of meer bewerkingen. Een transactie zorgt ervoor dat al die bewerkingen gezamelijk slagen of mislukken
  • Poison message handeling Wanneer een bericht niet kan verwerkt worden, verplaatst deze ze naar een dead letter queue

Zoals je ziet omvat Service Bus een rijke set aan features. Heb je één van bovenstaande nodig dan is Service Bus de juiste component voor jou.

Event Hub

De focus van Event Hub ligt op het verwerken van series van events of een stroom aan data zoals data van sensoren, devices, … Met Event Hub kan je grote hoeveelheden data ontvangen met het behouden van de volgorde. De data wordt voor X-aantal dagen gebufferd. Het zorgt ervoor dat er heel wat producers hun data kunnen publiceren op de Event Hub en de verwerkers ervan op hun tempo de data kunnen verwerken.

Event Hub werkt op basis van partitions. Elk bericht dat binnenkomt wordt op één partitie geplaatst op basis van bepaalde metadata of willekeurig.

Op een partitie kan binnen een consumer group maar één consumer de berichten lezen. De consumer group zorgt ervoor dat er op elke partitie één consumer actief is. Een consumer kan wel luisteren op meerdere partities.

Over consumer groups heen kunnen wel meerdere consumers dezelfde patition lezen.

Bij consumers spreekt men over een client side cursor. Dit wil zeggen dat de consumer bijhoudt welk bericht hij laatst verwerkt heeft. Valt de consumer eruit dan zal hij bij het heropstarten vanaf de cursor opnieuw beginnen te verwerken.

Hoe lang de berichten bewaard blijven op de partition wordt bepaald bij het aanmaken van de Event Hub.

IoT Hub

Zoals het in de naam staat ligt de focus van IoT Hub op de ingress van data van miljoenen IoT-sensoren. Deze service is ook één van de enige waar tweeweg communicatie over dezelfde bus mogelijk is. Er zijn verschillende protocollen beschikbaar om naar IoT hub te verbinden:

  • HTTPS
  • MQTT
  • MQTT over websockets
  • AMQP
  • AMQP over websockets

De focus ligt heel hard op security dus ieder device heeft zijn eigen unieke identity en moet TLS 1.2 ondersteunen. Als een bepaald device gecompromitteerd wordt kan de toegang voor dit device individueel verwijderd worden. Het nadeel aan de TLS 1.2 requirement is dat je al wat rekenkracht nodig hebt om dit te kunnen ondersteunen dus het is niet voor ieder device weggelegd.

Onderliggend is één van de componenten waaruit IoT Hub bestaat Event Hubs.

IoT Hub zelf bestaat uit enkele verschillende onderdelen:

  • Device Twin
  • IoT Edge
  • Device Provisioning Service

Bepaalde van deze onderdelen kun je hele boeken van schrijven maar ik wil hieronder kort even toelichten voor wat deze onderdelen dienen.

Device Twin

Het doel van de device twin is het voorstellen van de staat van een device, maar ook data zoals configuratie en metadata over het device. Men spreekt hier over tags, desired en reported properties.

De bedoeling van tags is het opslaan van metadata die alleen in de cloud blijft zoals naam, locatie, …

Met de desired properties stel je bepaalde waarden in voor een device zoals frequentie van rapportering, temperatuur alarm, … Zodra het device online komt en de desired properties ingelezen hebt, gaat het device de reported properties gaan bijwerken. Zo kun je gaan opvolgen dat de parameters gerepliceerd zijn naar het device maar het is ook perfect mogelijk dat het device de settings niet ondersteund of bijgestuurd heeft met een andere waarde.

IoT Edge

In bepaalde gevallen is het niet mogelijk om één of meerdere devices rechtstreeks naar de cloud te laten verbinden. De sensoren die werken op oudere protocollen of de hoeveelheid data on-the-edge is te groot om naar de cloud te gaan streamen. In deze use-cases en andere kan men een edge pc gaan inzetten. Deze edge pc kan dan de nodige zaken gaan vertalen, omvormen of gaan aggregeren om dan naar de cloud te gaan versturen.

Azure IoT Edge bestaat uit een runtime voor on-the-edge en in de cloud. On-the-edge kan je modules gaan draaien die de data capteren en verwerken. In IoT Hub is het mogelijk om de modules en settings ervan te beheren.

Device Provisioning Service

Device Provisioning Service of DPS laat je toe om zonder enige interventie miljoenen devices op een veilige manier te gaan voorzien van de nodig configuratie.

Zoals je waarschijnlijk zelf gemerkt hebt is IoT Hub niet echt geschikt in combinatie met serverless functions en ligt de focus heel hard op het device aspect.

Event Grid

Event Grid is voor mij een combinatie van Service Bus en Event Hubs met het publish/subscribe patroon. De focus van Event Grid ligt op het verwerken van grote hoeveelheden events waarop je kan luisteren met geavanceerde filtering.

Een Event Source is een component die een event uitstuurt. Een Event Handler verwerkt het event.

Zoals je hierboven ziet zijn er al heel wat Event Sources standaard gekoppeld op de Event Grid.

Een voorbeeld zou kunnen zijn: bij het aanmaken van een device op IoT Hub krijg je een event binnen op een serverless function en daarmee configureer je de applicatie voor het ontvangen van de data.

Naast de standaard Event Source is het ook mogelijk om zelf je Custom Events te maken. Daarnaast zijn er standaard ook al een aantal Event Handlers of integratie voorzien zoals serverless, logic apps, …

Daarnaast heeft Event Grid nog een aantal leuke features zoals:

  • Retry Intervals Als van de event handlers de endpoint offline is zal Event Grid tot 24 uur proberen de berichten af te leveren.
  • Dead lettering Als een event niet verwerkt kan worden dan kan het event opgeslagen worden in een storage account om dan achteraf verwerkt te worden.
  • Filtering Je kan op de data van het event een filter plaatsen. Meerdere filters kunnen gecombineerd worden.

Conclusie

In de context van distributed applications is langs de kant van de producers IoT Hub niet de beste keuze aangezien de focus hier ligt op devices. Heb je een eenvoudige queue nodig of grote hoeveelheden data dan is Storage Queues de juiste keuze. Heb je één van de features van Service Bus nodig dan moet je hier niet aan twijfelen. Dan zitten we nog met de keuze tussen Event Hub en Event Grid. Heb je grote hoeveelheden events die moeten verwerkt worden, dan moet je kiezen voor Event Hub. Mijn standaard go-to service is Event Grid.

--

--