Este bine cunoscut faptul că limbajul de programare Java nu acceptă modularitatea. Această problemă a fost observată cu mult timp în urmă, încercări repetate au fost făcute pentru a corecta situația. Aceasta se referă în primul rând la proiectul Jigsaw.
Jigsaw puzzle - o imagine compozită de puzzle (un puzzle în care doriți să adăugați bucăți individuale pentru a face o fotografie). Fiecare piesă (modul) este conectată la altele (prin interfețe), pentru a obține o imagine completă (software).
Deci, ce este modularitatea, care sunt avantajele arhitecturii modulare a software-ului și ce să facă înainte de apariția Java 9? O arhitectură modulară software - este o abordare de a proiecta, în care programul este împărțit în componente independente, care pot interacționa între ele prin contracte descrise în mod clar. Aceste componente - module - ar trebui să aibă mai multe caracteristici. În primul rând - încapsulare (ei trebuie să se ascundă punerea în aplicare a acestora din mediul extern), al doilea - o conexiune slabă (module interacționează numai cu ajutorul unor contracte de pre-negociate), a treia - dinamica (posibila substituție „on the fly“, fără a fi nevoie să se oprească întreaga aplicație).
Ce trebuie făcut atunci când sarcina este de a dezvolta o arhitectură cu adevărat modulară în limba Java? Ajutorul vine de la OSGi (Open Services Gateway Initiative) - specificația sistemului modular dinamic și a platformei de servicii pentru aplicațiile Java dezvoltate de Alianța OSGi. Specificația descrie un model de dezvoltare software în care componentele au toate cele trei caracteristici descrise mai sus. Bazele conceptului OSGi sunt două entități: pachete și servicii.
Seturi OSGi
Când se dezvoltă software-ul Java, de regulă se utilizează biblioteci terțe. În lumea Java, bibliotecile sunt ambalate în fișiere speciale cu o extensie JAR (Java ARchive). Aceasta este o arhivă ZIP obișnuită, care conține clase Java (fișiere cu extensia .class). Cu toate acestea, utilizarea bibliotecilor poate fi dificilă.
De îndată ce începeți să utilizați orice bibliotecă în aplicația dvs., de obicei veți putea accesa toate clasele din această bibliotecă. Ideea este că dezvoltatorii de biblioteci nu au capacitatea de a ascunde clasele care sunt folosite pentru implementarea logicii lor interne. Astfel, dacă utilizați un cod care nu a fost destinat utilizării în afara bibliotecii, este posibil să întâlniți incompatibilități atunci când utilizați o versiune nouă a bibliotecii sau să întrerupeți funcționarea corectă.
O altă problemă este așa-numita JAR Hell. Mulți dezvoltatori au rupt multe copii despre el. Linia de jos este că odată ce începeți să utilizați diferite versiuni ale aceleiași biblioteci în proiectul dvs. (de obicei, proiecte mari care se dezvoltă în timp), este posibil să întâlniți o situație în care aceeași clasă are metode diferite în diferite versiuni ale bibliotecii. Java este proiectat să utilizeze prima versiune a bibliotecii, care va găsi încărcătorul de clasă. Astfel, dacă adresați codul unei clase la timpul de execuție, veți primi o eroare că metoda pe care o accesați nu există. Acest lucru se datorează faptului că, în stadiul de execuție, Java nu știe nimic despre versiunea bibliotecii care ar trebui folosită în acest sau acel scenariu.
Trebuie remarcat faptul că dezvoltatorii OSGi au decis să nu modifice structura fișierelor JAR pentru a furniza modularitate, ci au adăugat pur și simplu informații suplimentare în ele care sunt utilizate de mediul OSGi. Mai mult, aceste informații suplimentare nu afectează utilizarea fișierelor JAR în aplicațiile obișnuite Java. Pentru ca fișierul JAR să devină un set OSGi, se adaugă date care determină care pachete din acest set sunt disponibile în afara acestuia (Export-Package) și ce pachete de alte seturi sunt necesare pentru funcționarea acestui set (Import-Package). Este posibil să se precizeze atât versiunea API pe care setul o oferă pentru alte seturi, cât și versiunea sau intervalul de versiuni ale API pe care setul le cere pentru munca lor. Toate clasele setate care nu sunt în secțiunea exportată nu sunt disponibile în afara setului (Private). În acest fel, setul OSGi îndeplinește cerința unei conectivități slabe.
Acum majoritatea bibliotecilor Java sunt deja pregătite pentru OSGi, adică conțin informații pentru a fi executate în containerul OSGi. Există, de asemenea, multe instrumente și utilitare care vă permit să creați module pentru OSGi din fișiere JAR obișnuite.
Fig. 1. Import / export de pachete în seturi OSGi
Deoarece dependențele dintre seturi și interfețele furnizate de aceste seturi au versiuni clare, timpul de funcționare OSGi ușurează evitarea situațiilor JAR Hell pe care le-am descris mai sus.
Astfel, extinderea ușor a descrierii unui fișier JAR obișnuit și adăugarea suportului pentru această descriere în mediul de execuție, comunitatea OSGi a rezolvat problema creării de module în Java. Timpul de funcționare OSGi vă permite să încărcați și să descărcați din nou din nou seturi la momentul executării. În plus, OSGi monitorizează dependențele dintre seturi și le rezolvă dinamic.
Servicii OSGi
Deci, având seturi OSGi, putem dezvolta aplicații modulare care interacționează prin interfețe (API). Se pune întrebarea: de unde pot obține clasa care implementează interfața necesară? Adăugarea unei astfel de clase în setul API este o soluție proastă, deoarece În cadrul arhitecturii modulare, am convenit să nu folosim clasele interne ale seturilor din afara acestor seturi. Ați putea folosi șablonul "fabrica" pentru a implementa interfața și a adăuga-o la setul API, dar pentru a dezvolta de fiecare dată când o nouă clasă care ascunde implementarea interfeței nu pare a fi cea mai bună idee.
OSGi rezolvă problema găsirii implementării interfeței prin intermediul registrului de servicii. Un set poate înregistra o implementare cu interfața sa de descriere din registrul de servicii. Un set care utilizează o interfață dintr-un alt set poate căuta registrul pentru implementarea dorită a interfeței de care are nevoie. În mod tipic, serviciile de înregistrări de seturi se execută în containerul OSGi. În plus, în registrul de servicii, aceleași interfețe pot fi înregistrate cu diferite implementări și date suplimentare de identificare. În acest caz, un set care caută registrul pentru serviciul de care are nevoie poate selecta cel mai potrivit (de exemplu, utilizând filtrarea).
Arhitectura Microservice în Java Virtual Machine
- Ușor (atunci când se dezvoltă un micro-serviciu, doar o anumită parte a funcționalității este implementată și nu este nevoie să vă faceți griji cu privire la alte părți ale programului).
- Simplitatea înlocuirii (dacă decideți că, în implementarea actuală, serviciul nu face față sarcinilor sale, îl puteți înlocui cu ușurință și îl puteți înlocui cu o nouă versiune fără a influența alte părți ale programului.) În plus, fără a opri actualul software.
- Reutilizare (deoarece microservice efectuează o sarcină mică, poate fi refolosită acolo unde este necesar).
După cum se poate observa din descrierea de mai sus, dezvoltatorii aplicațiilor modulare care utilizează OSGi și-au bucurat mult timp de toate avantajele unei arhitecturi de micro-servicii, dar numai în cadrul mașinii virtuale Java. Fiecare set cu OSGi, care publică serviciul în registru, este un microserviciu în Java Virtual Machine, JVM (în lumea OSGi aceste microservicii sunt numite μServices).
Red Hat JBoss Fuse
Noi, la Centrul pentru Software Solutions, folosim toate avantajele OSGi atunci când dezvoltăm software pentru operatorii de telecomunicații, asigurări, companii de procesare. Pentru a face acest lucru, folosim produsul Red Hat JBoss Fuse, în special configurația Fuse Fabric. Platforma JBoss Fuse oferă un mediu flexibil OSGi pentru executarea unei aplicații modulare.
Astăzi, cerințele software, cum ar fi continuitatea muncii, posibilitatea unei scalări orizontale ușoare, ușurința implementării și disponibilitatea instrumentelor de gestionare a cluster-ului pentru software-ul cluster. Fabric Fabric rezolvă aceste probleme. Tehnologia vă permite să implementați mai multe exemple de Red Hat JBoss Fuse și să le îmbinați într-un cluster și oferă, de asemenea, un instrument de management centralizat pentru mediul rezultat.
În cadrul Fabric Fuse, există următoarele abstracții:
- Caracteristicile sunt o colecție de seturi OSGi care implementează orice funcție funcțională.
- Profilurile reprezintă o colecție de caracteristici care trebuie efectuate într-un singur container și setări de configurare pentru seturile care sunt incluse în caracteristică.
- Containerele (containerele) sunt procese JVM individuale care rulează pe un anumit nod al unui cluster Fuse Fabric care rulează un container Red Hat JBoss Fuse.
Fig. 3. Ierarhia entității în Fabric Fuse
Astfel, orice software care se bazează pe tehnologia siguranțelor Fabric este format din OSGi-seturi sunt grupate în funcții și desfășurate în cadrul unei singure JVM-proces pe unul sau mai multe noduri din cluster în conformitate cu un profil predeterminat.
Mediul Fuse Fabric conține multe instrumente care facilitează gestionarea clusterului rezultat. Putem crea profiluri, să creăm containere pe baza profilurilor, să creăm / ștergem / să începem / să oprim containerele de pe orice gazdă care face parte din cluster, să conectăm noi noduri de cluster și așa mai departe. Și toate aceste acțiuni putem efectua on-line, adică fără a întrerupe funcționarea nodurilor rămase ale clusterului. Mediul acceptă capacitatea de a stoca mai multe versiuni de profile, caracteristici, seturi OSGi.
În mediul rezultat, seturile OSGi pot interacționa nu numai în interiorul aceluiași container, ci și se invocă reciproc în recipiente diferite (chiar și în cadrul unor gazde diferite). Această caracteristică este furnizată de tehnologia Distributed OSGi. În plus, cu costuri minime de dezvoltare, fiecare serviciu care oferă pachetul OSGi poate fi transformat într-un serviciu REST / web care poate fi apelat de la sisteme externe.
Astfel, folosind Fuse Fabric, putem crea arhitectura mikroservisnuyu care acceptă configurarea ușoară și implementarea, performanța izolată a serviciilor din cadrul sale JVM-procese (cu setări specifice ale acestora, de exemplu, diferite setări ale colectorului de gunoi), serviciile interacționează unele cu altele pe utilizând un protocol ușor.
pentru că produs Red Hat JBoss Siguranta se bazeaza pe Open stiva Source de tehnologie Apache ServiceMix la dispoziția noastră, există tehnologii puternice, cum ar fi Apache ActiveMQ (punerea în aplicare a caietului de sarcini JMS), Apache Camel (punerea în aplicare a modelelor de proiectare enterprise application), Apache CXF (bibliotecă pentru REST dezvoltare / web -Servicii), Blueprint (oferă posibilitatea introducerii dependențelor), Spring, etc. Deoarece aceste tehnologii se integrează perfect între ele în Red Hat JBoss Fuse, acest lucru reduce semnificativ timpul de dezvoltare a funcționalității necesare.