Útmutató reaktív mikroszolgáltatásokhoz a Lagom Framework használatával

1. Áttekintés

Ebben a cikkben a Lagom keretrendszerét és megvalósítson egy példa alkalmazást reaktív mikroszolgáltatások által vezérelt architektúra segítségével.

Egyszerűen fogalmazva, a reaktív szoftveralkalmazások az üzenetvezérelt aszinkron kommunikációra támaszkodnak és rendkívül magas szintűek Fogékony, Rugalmas és Rugalmas a természetben.

A mikroszolgáltatás-vezérelt architektúra alatt a rendszert határokra osztottuk az együttműködési szolgáltatások között a célok elérése érdekében Elkülönítés, Autonómia, Egyetlen felelősség, Mobilitásstb. E két fogalom további elolvasásához olvassa el a Reaktív kiáltvány és a Reaktív mikroszolgáltatások architektúráját.

2. Miért Lagom?

A Lagom egy nyílt forráskódú keretrendszer, amely a monolitokról a mikroszolgáltatások által vezérelt alkalmazás architektúrára való áttérést szem előtt tartva épült fel. Összefoglalja a mikroszolgáltatások által vezérelt alkalmazások felépítésének, futtatásának és felügyeletének összetettségét.

A kulisszák mögött a Lagom keretrendszer a Play Framework-et, egy Akka üzenet-vezérelt futást, a Kafka-t használja a szolgáltatások szétválasztására, az események beszerzésére és a CQRS mintákra, valamint a ConductR támogatást a mikrotartalmak megfigyeléséhez és méretezéséhez a konténer környezetben.

3. Hello Világ Lagomban

Létrehozunk egy Lagom alkalmazást, amely kezeli a felhasználó üdvözlő kérését, és válaszol egy üdvözlő üzenettel, valamint az adott nap időjárási statisztikáival.

Két különálló mikrohelyzetet fejlesztünk ki: Üdvözlet és Időjárás.

Üdvözlet összpontosítani fog egy üdvözlő kérelem kezelésére, kölcsönhatásba lépni az időjárási szolgálattal, hogy válaszoljon a felhasználónak. A Időjárás A mikroszolgáltatás kiszolgálja a mai időjárási statisztikák iránti kérelmet.

A meglévő felhasználó interakciója esetén Üdvözlet mikroszolgáltatás, a különböző üdvözlő üzenet megjelenik a felhasználó számára.

3.1. Előfeltételek

  1. Telepítés Scala (jelenleg a 2.11.8 verziót használjuk) innen
  2. Telepítés sbt build eszköz (jelenleg 0.13.11-et használunk) innen

4. Projekt beállítása

Most nézzük meg gyorsan a működő Lagom rendszer felállításának lépéseit.

4.1. SBT Build

Hozzon létre egy projektmappát lagom-hello-world amelyet a build fájl követbuild.sbt. A Lagom rendszer általában egy sor készletből áll sbt épít minden egyes építéssel a kapcsolódó szolgáltatások csoportjának:

Organization in ThisBuild: = "com.baeldung" scalaVersion in ThisBuild: = "2.11.8" lagomKafkaEnabled in ThisBuild: = false lazy val greetingApi = project ("greeting-api") .settings (version: = "1.0-SNAPSHOT", libraryDependencies ++ = Seq (lagomJavadslApi)) lusta val greetingImpl = project ("greeting-impl") .enablePlugins (LagomJava) .settings (verzió: = "1.0-SNAPSHOT", libraryDependencies ++ = Seq (lagomJavadslPersistenceCassendsra)). greetingApi, weatherApi) lusta val weatherApi = project ("weather-api") .beállítások (verzió: = "1.0-SNAPSHOT", libraryDependencies ++ = Seq (lagomJavadslApi)) lusta val weatherImpl = project ("weather-impl"). enablePlugins (LagomJava) .settings (verzió: = "1.0-SNAPSHOT") .dependsOn (weatherApi) def projekt (id: String) = Projekt (id, base = fájl (id))

Először is megadtuk a szervezet adatait, scala verzió, és letiltva Kafka a jelenlegi projekthez. A Lagom két külön projekt egyezményét követi minden egyes mikroszolgáltatáshoz: API projekt és megvalósítási projekt.

Az API projekt tartalmazza azt a szolgáltatási felületet, amelytől a megvalósítás függ.

Függőségeket adtunk hozzá a vonatkozó Lagom modulokhoz, mint például lagomJavadslApi, lagomJavadslPersztenceCassandra a Lagom Java API használatához mikroszolgáltatásainkban és a perzisztens entitással kapcsolatos események tárolásához a Cassandra, illetőleg.

Továbbá a üdvözlet-impl projekt függ a időjárás-api projekt az időjárási statisztikák beolvasására és kiszolgálására a felhasználó üdvözlése közben.

A Lagom plugin támogatásához hozzáadódik egy plugin mappa létrehozása a plugins.sbt fájl, a Lagom plugin bejegyzésével. Minden szükséges támogatást biztosít alkalmazásunk felépítéséhez, futtatásához és telepítéséhez.

Továbbá a sbteclipse A plugin hasznos lesz, ha az Eclipse IDE-t használjuk ehhez a projekthez. Az alábbi kód mindkét plugin tartalmát mutatja:

addSbtPlugin ("com.lightbend.lagom"% "lagom-sbt-plugin"% "1.3.1") addSbtPlugin ("com.typesafe.sbteclipse"% "sbteclipse-plugin"% "3.0.0")

Teremt projekt / épít.tulajdonságok fájlt, és adja meg sbt használható verzió:

sbt.verzió = 0,13,11

4.2. Projektgenerálás

Futás sbt A projektgyökérből a parancs a következő projektsablonokat hozza létre:

  1. üdvözlet-api
  2. üdvözlet-impl
  3. időjárás-api
  4. időjárás-impl

Mielőtt elkezdenénk megvalósítani a mikroszolgáltatásokat, tegyük hozzá a src / main / java és src / main / java / resources mappák az egyes projekteken belül, a Maven-szerű projektkönyvtár-elrendezés követése érdekében.

Két dinamikus projekt generálódik belül project-root / target / lagom-dynamic-projektek:

  1. lagom-internal-meta-project-cassandra
  2. lagom-internal-meta-project-service-locator

Ezeket a projekteket a Lagom belsőleg használja.

5. Szolgáltatási felület

Ban,-ben üdvözlet-api projektben megadjuk a következő felületet:

nyilvános felület A GreetingService kiterjeszti a Service {public ServiceCall handleGreetFrom (String felhasználó) szolgáltatást; @Orride default Descriptor descriptor () {return named ("greetingservice") .withCalls (restCall (Method.GET, "/ api / greeting /: fromUser", this :: handleGreetFrom)) .withAutoAcl (true); }}

GreetingService leleplezi handleGreetFrom () kezelni a felhasználó üdvözlő kérését. A ServiceCall Az API-t használják ezeknek a módszereknek a visszatérési típusaként. ServiceCall két típusú paramétert vesz fel Kérés és Válasz.

A Kérés paraméter a bejövő kérelem üzenet típusa, és a Válasz A paraméter a kimenő válaszüzenet típusa.

A fenti példában nem a kérelem hasznos terhelését használjuk, hanem a kérés típusa Nem használt, és Válasz típus a Húr üdvözlő üzenet.

GreetingService a meghívás során használt tényleges szállításhoz való hozzárendelést is meghatározza, az alapértelmezett megvalósításának biztosításával Service.descriptor () módszer. Nevű szolgáltatás üdvözletszolgáltatás visszatér.

handleGreetFrom () a szolgáltatási hívás a Rest azonosítóval van leképezve: KAP módszer típusa és elérési útja / api / greeting /: fromUser feltérképezve handleGreetFrom () módszer. A szolgáltatásazonosítókkal kapcsolatos további részletekért tekintse meg ezt a linket.

Ugyanezeken a vonalakon definiáljuk WeatherService interfész a időjárás-api projekt. weatherStatsForToday () módszer és leíró () módszer nagyjából magától értetődő:

nyilvános felület Az WeatherService kiterjeszti a {public serviceCall weatherStatsForToday () szolgáltatást; @Orride default Descriptor descriptor () {return named ("weatherservice") .withCalls (restCall (Method.GET, "/ api / weather", this :: weatherStatsForToday)) .withAutoAcl (true); }};

WeatherStats definíciója: a különböző időjárási mintákra vonatkozó értékek és véletlenszerű keresés a nap időjárás-előrejelzéséhez:

public enum WeatherStats {STATS_RAINY ("Esőbe megy, esernyőt vesz"), STATS_HUMID ("Nagyon nedves leszek, vigyünk vizet"); public static WeatherStats forToday () {return VALUES.get (RANDOM.nextInt (SIZE)); }}

6. Lagom Persistence - Események beszerzése

Egyszerűen fogalmazva, egy olyan rendszerben, amely a Események beszerzése, képesek leszünk az összes változás rögzítésére, mivel megváltoztathatatlan tartományi események vannak egymás után. A jelenlegi állapot az események visszajátszásával és feldolgozásával származik. Ez a művelet lényegében a foldBal a funkcionális programozási paradigmából ismert művelet.

Az események beszerzése az események hozzáfűzésével és a meglévő események frissítésének és törlésének elkerülésével segíti a magas írási teljesítmény elérését.

Most nézzük meg az üdvözlő-impl projekt kitartó entitásunkat, GreetingEntity:

public class GreetingEntity kiterjeszti a PersistentEntity {@Orride public Behavior initialBehavior (Opcionális snapshotState) {BehaviorBuilder b = newBehaviorBuilder (new GreetingState ("Hello")); b.setCommandHandler (ReceivedGreetingCommand.class, (cmd, ctx) -> {String fromUser = cmd.getFromUser (); String currentGreeting = állapot (). getMessage (); return ctx.thenPersist (új ReceivedGreetingEvent (fromUser), evt -> ctx.reply (currentGreeting + fromUser + "!"));}); b.setEventHandler (ReceivedGreetingEvent.class, evt -> state (). withMessage ("Hello Hello")); visszatérés b.build (); }}

Lagom biztosítja PersistentEntity API bejövő típusú események feldolgozásához Parancs keresztül setCommandHandler () módszerek és az állapotváltozások, mint típusú események Esemény. A tartományobjektum állapotát az esemény az aktuális állapotra történő alkalmazásával frissíti a setEventHandler () módszer. A kezdeti viselkedés () absztrakt módszer határozza meg a Viselkedés az entitás.

Ban ben kezdeti magatartás (), mi eredeti GreetingState „Hello” szöveg. Ezután meghatározhatjuk a ReceivedGreetingCommand parancskezelő - amely a ReceivedGreetingEvent Az esemény és az eseménynapló megmarad.

GreetingState újraszámítja a „Hello Hello” -ra a ReceivedGreetingEvent eseménykezelő módszer. Mint korábban említettük, nem hívunk telepítőket, hanem egy új példányt hozunk létre Állapot az éppen feldolgozott eseménytől.

Lagom követi a GreetingCommand és GreetingEvent interfészek az összes támogatott parancs és esemény összefogásához:

nyilvános felület A GreetingCommand kiterjeszti a Jsonable-t {@JsonDeserialize public class }}}
nyilvános felület A GreetingEvent kiterjeszti a Jsonable {class ReceivedGreetingEvent megvalósítja a GreetingEvent {@JsonCreator public ReceivedGreetingEvent (String fromUser) {this.fromUser = fromUser; }}}

7. Szolgáltatás megvalósítása

7.1. Üdvözlő szolgálat

public class GreetingServiceImpl megvalósítja a GreetingService {@Inject public GreetingServiceImpl (PersistentEntityRegistry persistentEntityRegistry, WeatherService weatherService) {this.persistentEntityRegistry = persistentEntityRegistry; this.weatherService = weatherService; persistentEntityRegistry.register (GreetingEntity.class); } @Orride public ServiceCall handleGreetFrom (String user) {return request -> {PersistentEntityRef ref = persistentEntityRegistry.refFor (GreetingEntity.class, user); CompletableFuture greetingResponse = ref.ask (új ReceivedGreetingCommand (felhasználó)) .toCompletableFuture (); CompletableFuture todaysWeatherInfo = (CompletableFuture) weatherService .weatherStatsForToday (). Invoke (); próbáld ki a {return CompletableFuture.completedFuture (greetingResponse.get () + "A mai időjárási statisztikák:" + todaysWeatherInfo.get (). getMessage ()); } catch (InterruptedException | ExecutionException e) {return CompletableFuture.completedFuture ("Elnézést kérünk, hiba történt a végén, azon dolgozunk"); }}; }}

Egyszerűen fogalmazva, beadjuk a PersistentEntityRegistry és WeatherService függőségek felhasználásával @ Injekció (által biztosított Guice keret), és regisztráljuk a perzisztenseket GreetingEntity.

A handleGreetFrom () megvalósítás küld ReceivedGreetingCommand hoz GreetingEntity az üdvözlő karakterlánc aszinkron módon történő feldolgozásához és visszaadásához CompletableFuture végrehajtása CompletionStage API.

Ehhez hasonlóan aszinkron hívást is kezdeményezünk Időjárás mikroszolgáltatás a mai időjárási statisztikák lekérésére.

Végül összefűzzük mindkét kimenetet, és visszaadjuk a végeredményt a felhasználónak.

A szolgáltatásleíró felület megvalósításának regisztrálása GreetingService Lagommal alkossunk GreetingServiceModule osztály, amely kiterjed AbstractModule és megvalósítja ServiceGuiceSupport:

public class GreetingServiceModule kiterjeszti az AbstractModule szolgáltatást a ServiceGuiceSupport {@Orride protected void configure () {bindServices (serviceBinding (GreetingService.class, GreetingServiceImpl.class)); bindClient (WeatherService.class); }} 

Emellett a Lagom belsőleg használja a Play keretrendszert. Így hozzáadhatjuk modulunkat a Play engedélyezett moduljainak listájához src / main / resources / application.conf fájl:

play.modules.enabled + = com.baeldung.lagom.helloworld.greeting.impl.GreetingServiceModule

7.2. Meteorológiai szolgálat

Miután megnézte a GreetingServiceImpl, WeatherServiceImpl nagyjából egyértelmű és magától értetődő:

a public class WeatherServiceImpl megvalósítja a WeatherService {@Orride public ServiceCall weatherStatsForToday () {return req -> CompletableFuture.completedFuture (WeatherStats.forToday ()); }}

Ugyanazokat a lépéseket követjük, mint fentebb az üdvözlő modulnál, hogy regisztráljuk az időjárási modult a Lagomnál:

a WeatherServiceModule nyilvános osztály kiterjeszti az AbstractModule szolgáltatást a ServiceGuiceSupport {@Orride védett void configure () {bindServices (serviceBinding (WeatherService.class, WeatherServiceImpl.class)); }}

Ezenkívül regisztrálja az időjárási modult a Play engedélyezett moduljainak keretrendszerébe:

play.modules.enabled + = com.baeldung.lagom.helloworld.weather.impl.WeatherServiceModule

8. A projekt futtatása

Lagom megengedi tetszőleges számú szolgáltatás futtatása egyetlen paranccsal.

A projektünket az alábbi paranccsal indíthatjuk el:

sbt lagom: runAll

Ezzel elindul a beágyazás Szolgáltatáskereső, beágyazva Cassandra majd párhuzamosan indítsa el a mikroszolgáltatásokat. Ugyanez a parancs újratölti az egyéni mikroszolgáltatásunkat is, amikor a kód úgy változik, hogy mi nem kell kézzel újraindítani őket.

Koncentrálhatunk logikánkra, és a Lagom kezeli az összeállítást és az újratöltést. Miután sikeresen elindult, a következő kimenetet látjuk:

................ [info] A Cassandra kiszolgáló 127.0.0.1:4000-nél fut [info] A szolgáltatás lokátor a // localhost címen fut: 8000 [info] A szolgáltatás átjárója a / / localhost: 9000 [info] A szolgáltatás időjárás-hallgatása a HTTP-n 0: 0: 0: 0: 0: 0: 0: 0: 0: 56231-re és a szolgáltatások interakciójára az [info] szolgáltatáson keresztül. : 0: 0: 0: 0: 0: 0: 0: 49356 [info] (A szolgáltatások elindultak, a leállításhoz nyomja meg az Enter billentyűt és térjen vissza a konzolhoz ...)

Miután sikeresen elindultunk, kérhetünk egy göndör üdvözlést:

curl // localhost: 9000 / api / üdvözlet / Amit

A következő kimenetet látjuk a konzolon:

Szia Amit! A mai időjárási statisztikák: Esőre megy, Vegyük az esernyőt

Ugyanazon curl kérés futtatása egy meglévő felhasználó számára megváltoztatja az üdvözlő üzenetet:

Üdv Ismét Amit! A mai időjárási statisztikák: Esőre megy, Vegyük az esernyőt

9. Következtetés

Ebben a cikkben kitértünk arra, hogyan használhatjuk a Lagom keretrendszert két aszinkron módon interakcióban lévő mikropiac létrehozására.

A cikk teljes forráskódja és összes kódrészlete elérhető a GitHub projektben.