Alen Adanić
Autor:
Alen Adanić

Programer za C#.NET programski jezik

Izazovi implementacije ESB-a (MassTransit, RabbitMQ)

Što su enterprise service bus (ESB), MassTransit i RabbitMQ?

Trenutno radimo na sustavu koji se temelji na mikroservisnoj arhitekturi. Radeći na takvom sustavu došli smo do potrebe za komunikacijom između neovisnih i autonomnih servisa, odnosno poslovna logika na jednom servisu mora obavijestiti nekoliko drugih servisa o svojim promjenama.

Enterprise service bus (dalje ESB) komunikacijski je sustav  različitih aplikacija i servisa u servisno orijentiranoj arhitekturi (SOA). ESB omogućuje razmjenu poruka između servisa bez ovisnosti o dostupnosti servisa i čekanja (decoupling / temporal decoupling).

MassTransit je service bus framework (sabirnica) za .NET. RabbitMQ Client API implementira service bus framework na nižoj razini apstrakcije od MassTransita.

Bitna napomena je da u ESB-u ne postoji nikakva logika, služi samo za prijenos poruka, a servisi imaju zadatak implementacije poslovne logike.

Neke od mogućnosti bile su postavljanje dll reference ili web reference na taj servis, ali tako stvaramo coupling (i temporal coupling). Rješenje naših problema je ESB koji na temelju publisher/subscriber pattern-a omogućava decouplanu arhitekturu. Servis na kojem su se dogodile promjene podigne događaj (event), a svi ostali servisi koji su pretplaćeni na taj događaj primaju poruku o događaju.

MassTransit ili RabbitMQ Client API?

Pred nama je stajao izbor odabira tri implementacije ESB-a:

-        RabbitMQ Client API (native transport API, open source)

-        MassTransit (service bus, open source)

-        NServiceBus (service bus, commercial)

Komercijalna implementacija odmah je izašla izvan izbora jer je komercijalna tj. plaća se (omjer potreba i troškova nam nije odgovarao).

RabbitMQ Client API je implementacija na nižem nivou apstrakcije, stoji direktno iznad AMQP protokola (Advanced Message Queuing Protocol). Ovdje bi morali implementirati sve strategije obrade poruka ručno. Nudi najviše opcija za konfiguraciju, ali i zahtjeva najviše rada.

MassTransit je apstrakcija nad RabbitMQ-om. Većinu funkcionalnosti pruža “out of the box”.

Na idućoj tablici možemo vidjet prednosti i nedostatke korištenja MassTransit-a i RabbitMQ-a.

MassTransit

RabbitMQ Client API

Error handling, Message Retrieve i konkurentnost podržani su out of the box – štedi vrijeme.

Sve je potrebno ručno implementirati.

Skriva kompleknost sustava transporta (RabbitMQ) – jednostavnije je.

Prikazuje svu svoju kompleksnost – složenije, ali pruža mogućnost konfiguriranja naprednih funkcionalnosti.

Funkcionira na temelju tipova (types) – nije se potrebno zamarati sa serijalizacijom i deserijalizacijom kod publisha/consuma.

Koristi stringove.

Podržava više transporta (RabbitMq, InMemory…) i lagano za zamjenu, malo konfiguriranja.

Podržava samo jedan transport. Ako kojim slučajem želimo zamijeniti način transporta – moramo ispočetka napisati kod.

Razvijeno imajući na umu unit testove (nuget paketi).

Moraju se napisati iznova.

Naši zahtjevi bili su jednostavnost, vrijeme i gotove funkcionalnosti pa smo se prema tome odlučili za MassTransit rješenje.

MassTransit

Kako funkcionira MassTransit? 

 Ukratko, postoje dvije strane, Publisher strana (strana koja šalje naredbu ili događaj) i Consumer strana (strana koja konzumira/pretplaćena na naredbu ili događaj). Publisher i Consumer moraju nekako komunicirati, a to rade preko Exchange-ova i Queue-ova. Način na koji Publisher i Consumer znaju gdje poslati poruku, odnosno gdje slušati događaje jest konfiguracija endpointova. Kada šaljemo ili se pretplaćujemo na poruke definiramo servise na koje slušamo, a oni su formata:

rabbitmq://{adresa}/{ime_endpointa}

 Na idućoj slici prikazan je primjer komunikacije između Publisher-a i Consumer-a.

consumer-publisher

Na prethodnoj tablici moguće je vidjeti okvirne prednosti MassTransita. Na idućoj listi ćemo malo detaljnije proći kroz funkcionalnosti koje MassTransit nudi, a korisne su:

  •          Automatsko kreiranje Queue-ova i Exchange-ova

     o   MassTransit ne poznaje razliku između Exchange-ova i Queue-ova te on za svaki tip poruke kreira Exchange)

  •         Bazna sučelja

     o   Osim na servise, možemo se pretplatiti i na bazna sučelja (base interfaces). Ovo je odlična funkcionalnost jer omogućuje verzioniranje. Nije potrebno mijenjati sustav nego samo naslijediti drugačije sučelje i pretplatiti Consumera na njega.

  •          Message scheduling

     o   Slanje poruka u točno određeno vrijeme (ovisnost na Quartz.Net nuget paket)

  •         Monitoring

     o   Postoje razni načini nadzora sustava (za svrhe logiranja, debug-a,  statistike ili samo za nadzor potrošnje resursa)

     o   Nadzor poruka – Observer interfaces (IRecieveObserver, IConsumeObserver, ISendObserver, IPublishObserver) i svaki ima metode za slučajeve prije obrade poruke, u tijeku obrade, nakon obrade i u slučaju pogreške

     o   Nadzor potrošnje resursa – PerformanceCounters dostupan na konfiguriranju service bus-a

  •           DI

     o   Odlično za unit testing i ALM

  •          Reacting to failure

     o   Connection management feature – svaki puta kada je veza prekinuta, automatski je obnavlja

     o   Skipped queue – za poruke koje ne mogu biti usmjerene

     o   Retry mehanizam – postoje različite retry procedure za ponovo slanje poruke (Immediate, Intervals, Exponential, Incremental)

     o   Error queue – ovdje završavaju poruke koje se ne mogu procesuirati

Podizanje RabbitMQ servisa i detalji implementacije

Kako bi postavili MassTransit potrebno je nekoliko predradnji:

  •          Instalirati Erlang
  •          Instalirati RabbitMQ
  •          Dodati referencu na MassTransit nuget paket preko Nuget Package Manager-a            

Redoslijed instalacije je bitan. Potrebno je paziti da su Erlang i RabbitMQ verzije kompatabilne.

Konfiguracija usera, virtual hostova i ostalih parametara moguća je i kroz web API koji je dostupan na http://localhost:15672 i moguće ga je aktivirati naredbom:

rabbitmq-plugins enable rabbitmq_management

Kada smo instalirali sve potrebno možemo napisati jednostavnog Consumer-a i Publisher-a.

Primjer jednostavnog Publishera:

publisher example

Primjer jednostavnog Consumera:

consumer

Primjer podizanja endointa i definiranja Consumera:

endpoint

Kada smo u sustav implementirali MassTransit postavili smo si nekoliko pitanja:

  •          Kako ćemo znati kada se dogodila pogreška i kako ćemo pronaći informacije o poruci?
  •          Kako ćemo se osigurati da se ista poruka ne pošalje više puta?

Prvo pitanje rješili smo tako da smo implementirali retry policy. Konfigurirali smo sustav na način da smo dodali interval ponavljanja nekonzumiranih poruka. Ukoliko se nakon definiranog puta poruka i dalje ne može konzumirati šalje se email administratorima o grešci, a poruka se proslijedi u error queue (ovo vrijedi za prolazne greške – nedostupnost servera, loše perfomanse baze…). Više možete vidjeti na slici ispod.

retry policy

Kako smo osigurali da se ista poruka slučajno ne konzumira više puta? Koristili smo Idempotent pattern. Svaka poruka ima jedinstveni Guid i preko Guid-a provjeravamo je li poruka jedinstvena, a ako nije odbacujemo je.

Zaključak

Enterprise service bus je komunikacijski sustav različitih aplikacija i servisa u servisno orijentiranoj arhitekturi . Ovakva arhitektura nam omogućava decoupled (i temporal decoupled) sustav.

MassTransit, NServiceBus i RabbitMQ Client API različite su implementacije service bus-a. NServiceBus je komercijalan, od RabbitMQ Client API-a smo odustali jer, iako pruža više, zahtjeva i više rada. MassTransit je open source,  jednostavan i  pruža puno funkcionalnosti pa smo se zato odlučili za njega.

Način na koji MassTransit funkcionira jest da Publisher objavljuje događaje ili naredbe (command or events) određenom endpointu, na kojem ga slušaju Consumer-i koji procesuiraju ove naredbe i/ili događaje, a događaj i/ili naredbe putuju od Consumera do Publishera preko Exchang-a i Queue-a.

MassTransit nudi puno funkcionalnosti “out of the box”, a neke od njih su:

  • Automatsko kreiranje Queue-ova i Exchange-ova
  • Base interfaces versioning
  • Message scheduling
  • Monitoring
  • DI
  • Reacting to failure

MassTransit je dobar primjer besplatnog i open source service bus-a koji nudi niz funkcionalnosti za kreiranje distribuiranih aplikacija. U ovom postu smo prošli kroz nekoliko osnovnih funkcionalnosti koje MassTransit pruža (retry policy, monitoring, logging, exception handling…). Postoji niz ostalih funkcionalnosti (Sagas, Distributed Transactions…) te ako nekoga zanima više može potražiti na MassTransit stranicama. Source jednostavnog primjera implementacije MassTransita možete vidjeti na ovom linku.

Popularne teme
.NET ABAP ADFS Agile Always On Anemic Model Angular Azure Backbone BI BI projekti Bootstrap building people business inteligence Business Intelligence Change Chrome CI CITCON Claims compile Continuous Delivery continuous deployment Continuous Integration CSR d3js data data visualization Data visualization alati DDD dekompozicija dependency injection dinamička forma dinamički parametri dinamički query distribuirani razvoj Domain-Driven design DOP društvena odgovornost edge-based video analytics Eliminating waste enkapsulacija enterprise razvoj softvera ERP ETL Excel FIORI Frontend game Geopackage GPKG GIS Git Groovy heat map HICCUPS Hichert HTML IBCS interoperability invision IoT IPSO izvještavanje java java lambde benchmark JavaFX Javascript Jazz Build Engine JBE Jenkins jquery jqueryui jsfiddle JVM Kaizen Kanban KING ICT Kingovci Knockout kvaliteta leadership Lean M language Management Maven Metodologija microservices Microsoft mobile Mobility mockups moć monday game NetWeaver network nodejs OGC OKR open source optimizacija organizacija organizacijska struktura OutOfMemoryError outsourcing paginacija Performance performanse PERT PMI podatkovni skup pouzdanost Power BI Power Map Power Pivot Power Query Power View pretraga proces procjena Product Owner programming proizvod Project manager projektni plan radar Rational Team Concert razvoj tima Release resize responsive charts REST retrospektiva Rich-Domain model Roko Roić rolling wave planning RTC SAP scale scatterplot chart Scrum scrum team scrum tim service boundaries single responsibility principle Single Sign-On smart metering SoapUI social responsibility softver Software software prototyping Software Testing Club Spring Boot SQL standard sustav videonadzora svg Team team building team development Team Foundation Server terminski plan Testing tim timesheet timovi Toggl.com touch transakcijski nadzor tražilica Uspjeh Visual Studio vodstvo vodstvo leadership moć društvena odgovornost DOP social responsibility CSR vođenje projekata WBS Web Zagreb STC

PRIJAVA NA NEWSLETTER

Najnovije novosti iz ICT svijeta