-
Notifications
You must be signed in to change notification settings - Fork 0
JMS
Készítette: Hegedüs Ábel, Honfi Dávid
A jelen mérés során a hallgatók megismerkednek az üzenetsorok kezelésének szabványos módjával JMS segítségével. Ehhez kapcsolódóan betekintést nyernek a JMX keretrendszerbe, amely segítségével konfigurálhatóak az üzenetsorok és a JNDI címfeloldó technológiával, amellyel egyedi azonosítók alapján lehet referenciát kérni a megfelelő objektumokra (pl. üzenetsorok).
Az előző mérésen használt RabbitMQ alapú üzenetsorok hátránya, hogy az alkalmazások kizárólag az AMQP protokoll segítségével tudnak egymással kommunikálni. Ehelyett jó lenne, ha az elkészített alkalmazások tetszőleges üzenetsor kezelő keretrendszer felett futtathatóak lennének (elfedve a kommunikáció részleteit, például a protokollt). Erre ad lehetőséget a Java Message Service (JMS) szabványos alkalmazásprogramozási felület (API).
A JMS segítségével az alkalmazások képesek üzentek létrehozására, küldésére, fogadására és feldolgozására. A JMS igyekszik maximalizálni az alkalmazások hordozhatóságát különböző JMS szolgáltatók között egy adott üzenetküldő megoldásban. Segítségével megvalósítható az aszinkron és megbízható kommunikáció.
Egy vállalati alkalmazás szolgáltató a következő esetekben szokta az üzenetküldő APIt választani egy szorosan csatolt API helyett, ha:
- A szolgáltató azt szeretné elérni, hogy a komponensek ne függjenek más komponensek interfészeinek információitól (pl. hogyan kommunikál), hogy könnyen kicserélhetők legyenek.
- A szolgáltató azt szeretné, hogy az alkalmazása futni tudjon akkor is, ha nem minden komponense elérhető.
- Az alkalmazás üzleti modellje lehetővé teszi, hogy egy komponens információkat küldjön egy másiknak majd folytassa működését anélkül, hogy azonnal választ kapna.
Egy JMS alkalmazás következő részekből áll, ahogy az ábra is mutatja:
- A JMS szolgáltató (provider) implementálja a JMS interfészt, továbbá adminisztratív és vezérlési funkciókat tartalmaz.
- A JMS kliensek olyan Java nyelven írt programok vagy komponensek, amelyek üzeneteket termelnek és dolgoznak fel.
- Az üzenetek olyan objektumok, amelyek a kliensek között információkat visznek át.
- Az adminisztrált objektumok olyan előre konfigurált JMS objektumok, amelyeket egy adminisztrátor készített és a kliensek használják. Ilyen például a célállomás (destination) vagy a kapcsolatokezelő.
- A natív kliensek olyan programok, amelyek az üzenetküldő alrendszer natív API-ját használják a JMS API helyett (pl. egy Java kliens RabbitMQ alrendszert használva kommunikál egy natív RabbitMQ hozzáférést használó Python alapú klienssel).
A leggyakrabban használt megoldások a pont-pont összeköttetés és a hirdető/feliratkozó módszer.
- Pont-pont összeköttetés (point-to-point) esetén az alkalmazások az üzenetsorok, küldők és fogadók koncepcióira épülnek. Minden üzenetnek egy fogyasztója van, a küldőnek és a fogadónak nincsenek időzítési függései. A fogadó attól függetlenül megkaphatja az üzenetet, hogy a küldés időpontjában futott-e. Amennyiben az üzenet fogadása sikeres volt, akkor a fogadó erről visszajelez a küldőnek.
- A hirdető/feliratkozó (publish/subscribe) esetén a kliensek egy úgynevezett témára küldik az üzeneteket, a feliratkozók pedig ezen témákra iratkoznak fel a rendszerben. Ekkor az üzenetkezelő alrendszer biztosítja, hogy az üzenetek eljutnak az összes, adott témára feliratkozott klienshez. Ezáltal minden üzenetnek több fogyasztója lehet, a küldők és a feliratkozók között pedig időzítési függőség van. A kliens, amely feliratkozik egy témára, csak olyan üzeneteket kap meg, amelyek az után érkeztek, hogy a kliens feliratkozott. A fogyasztóknak ezen kívül aktívnak is kell maradniuk ahhoz, hogy az üzeneteket fogadni tudják.
Egy üzenetkezelő rendszer esetén két ehetőség van az üzeneteket fogadására.
- Szinkron üzenetfogadás esetén a fogadó explicit módon lekéri az üzenetet egy metódus meghívásával, amelyet az üzenetkezelő alrendszer biztosít (pl. egy receiveMessage metódus hívásával).
- Aszinkron üzenetfogadás esetén a kliens egy message listenert regisztrál be a rendszerbe, amely akkor fut le, ha érkezik egy üzenet. Ennek meghívását tehát az az üzenetkezelő rendszer biztosítja (pl. egy onMessage metódus meghívásával).
A Java Naming and Directory Interface (JNDI) API egy könyvtár és elnevezési funkcionalitást biztosító interfész Java alkalmazásokhoz. Segítségével az alkalmazások bármilyen típusú objektumot elnevezhetnek és tárolhatnak egy központi könyvtárban (legyen az akár valamilyen adatbázis, címtár vagy akár objektum- és szolgáltatástár). Az objektumokhoz az egyedi neveken felül attribútumok is hozzáadhatók. A JNDI biztosítja az alapvető könyvtárműveleteket, így támogatja a név és attribútumok alapján történő keresést.
Tehát például egy JNDI-t implementáló nagyvállalati rendszer esetén egy szükséges adat lekéréséhez a rendszer szolgáltatásait és adatait tároló komponenstől, jó esetben elég lehet megadni a kívánt adat egyedi névazonosítóját (JNDI nevét).
A JMS alkalmazások alapvető építőelemei a következők.
- Adminisztrált objektumok
- Kapcsolatok
- Munkamenetek (session)
- Üzenettermelők (producers)
- Üzenetfogyasztók (consumers)
- Üzenetek
Az elemek közötti kapcsolatokat ábrázolja az alábbi ábra.
A kapcsolatkezelő (connection factory) olyan adminisztrált objektum, amelynek segítségével a kliensek kapcsolatot teremtenek a szolgáltatóval. A kapcsolatkezelő tartalmazza az adminisztrátor által definiált kapcsolat konfigurációs paraméterek halmazát.
Context ctx = new InitialContext();
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
A mérés során a hallgatóknak át kell alakítaniuk az első mérésen készült programjukat olyan formába, hogy a folyamat egyes lépései közötti adatáramlás üzenetsorok segítségével legyen megoldva. Az összes csomópont külön Java folyamat legyen (nem csak thread), amelyek kizárólag a JMS API-n kommunikálnak, nincs központi szinkronizációs komponens.
A következő feladatokat kell elvégezni a mérés teljesítéséhez:
- Java osztályok átalakítása, a kommunikáció elkülönítése. Általában egy get és egy put metódus megvalósítása szükséges, amely magába foglalja a JMS-el való kommunikációt.
- Folyamat lépéseinek összekötése a megfelelő ki- és bemeneti sorok megadásával.
- A folyamat többször is futtatható legyen az JMX kezelő program használata nélkül (ne maradjon futást zavaró üzenet a sorokban).
További feladatok, amelyek közül legalább egy megoldása szükséges a maximális pontszám eléréséhez:
- Point-to-point összeköttetés helyett a program átalakítása publisher/subscriber alapú működésre.
- Egy saját MBean megvalósítása, amelynek legyen olyan operációja, amivel egy új folyamatpéldány indítható az attribútumokban beállított adatokkal.
A mérés után leadott jegyzőkönyvben szerepeljen a mérés elvégzéséhez szükséges lépések leírása megismételhető módon. Legyen benne a megvalósított folyamat rövid leírása, azok a műveletek, amelyeket az JMX felületén el kellet végezni, a létrehozott üzenetsorok és paramétereik. Szerepeljen benne az, hogy hogyan és mennyire kellett az eredeti programot megváltoztatni, hogyan valósították meg az egyes csomópont típusokat. Tartalmazzon megfelelő mennyiségű képernyőképet és útmutatót ahhoz, hogy hogyan kell lefuttatni az elkészült programot.
A beugró kérdések kizárólag ebben a dokumentumban leírtakat fogják visszakérdezni (lásd a lenti példakérdéseket), a lenti négy linkelt leírás a mérés elvégzéséhez szükséges pluszinformációkat tartalmazzák.
- Mik a JMS API használatának előnyei a RabbitMQ használatával szemben?
- Mi a JNDI rövidítés feloldása és mire használható?
- Rajzold fel a JMS API architektúráját!
- Mutasd be a JMS API programozási modelljét!
Az alábbi segédanyagok egyrészt bővebb elméleti ismereteket tartalmaznak, másrészt hasznosak lehetnek a mérés elvégzése során.
Java™ Message Service API Tutorial 1, 2, 3 fejezetek: Overview, Basic Programming Concepts, The JMS API Programming Model
Java Naming and Directory Interface™ Application Programming Interface Getting Started
Java Message Service API Architecture, JMS Message Model, JMS Common Facilities, JMS Point-to-Point Model, JMS Example Code