Úvod do Dubbo

1. Úvod

Dubbo je open-source RPC a rámec mikroslužieb od spoločnosti Alibaba.

Okrem iného pomáha vylepšiť správu služieb a umožňuje hladké preformátovanie tradičných monolitických aplikácií na škálovateľnú distribuovanú architektúru.

V tomto článku uvedieme Dubbo a jeho najdôležitejšie funkcie.

2. Architektúra

Dubbo rozlišuje niekoľko rolí:

  1. Poskytovateľ - kde je vystavená služba; poskytovateľ zaregistruje svoju službu do registra
  2. Kontajner - kde je služba iniciovaná, načítaná a spustená
  3. Spotrebiteľ - ktorý využíva vzdialené služby; spotrebiteľ si predplatí službu potrebnú v registri
  4. Register - kde bude služba zaregistrovaná a objavená
  5. Monitorovať - ​​zaznamenávať štatistické údaje o službách, napríklad frekvenciu vyvolávania služieb v danom časovom intervale

(zdroj: //dubbo.io/images/dubbo-architecture.png)

Spojenia medzi poskytovateľom, spotrebiteľom a registrom sú trvalé, takže kedykoľvek je poskytovateľ služieb nefunkčný, register dokáže zistiť poruchu a upovedomiť spotrebiteľa.

Register a monitor sú voliteľné. Spotrebitelia sa môžu pripojiť priamo k poskytovateľom služieb, ovplyvní to však stabilitu celého systému.

3. Maven závislosť

Predtým, ako sa ponoríme, pridajme k našej nasledujúcej závislosti pom.xml:

 com.alibaba dubbo 2.5.7 

Najnovšiu verziu nájdete tu.

4. Bootstrapping

Teraz si vyskúšame základné vlastnosti Dubbo.

Toto je minimálne invazívny rámec a veľa jeho funkcií závisí od externých konfigurácií alebo anotácií.

Oficiálne sa navrhuje, aby sme použili konfiguračný súbor XML, pretože to závisí od kontajnera Spring (momentálne jar 4.3.10).

Väčšinu jeho funkcií si ukážeme pomocou konfigurácie XML.

4.1. Register multicast - poskytovateľ služieb

Na rýchly štart budeme potrebovať iba poskytovateľa služieb, spotrebiteľa a „neviditeľný“ register. Register je neviditeľný, pretože používame sieť multicast.

V nasledujúcom príklade poskytovateľ povie svojim zákazníkom iba „ahoj“:

verejné rozhranie GreetingsService {Reťazec sayHi (Názov reťazca); } verejná trieda GreetingsServiceImpl implementuje GreetingsService {@Override public String sayHi (názov reťazca) {return "ahoj," + meno; }}

Aby bolo možné uskutočniť vzdialené volanie procedúry, spotrebiteľ musí zdieľať spoločné rozhranie s poskytovateľom služby, teda týmto rozhraním ZdravímSlužba musia byť zdieľané so spotrebiteľom.

4.2. Register multicast - registrácia služby

Poďme sa teraz zaregistrovať ZdravímSlužba do registra. Veľmi pohodlným spôsobom je použitie registra multicast, ak sú poskytovatelia aj spotrebitelia v rovnakej lokálnej sieti:

S vyššie uvedenou konfiguráciou fazule sme práve odhalili našu ZdravímSlužba na adresu URL pod dubbo: //127.0.0.1: 20880 a zaregistroval službu na adresu multicast špecifikovanú v .

V konfigurácii poskytovateľa sme tiež deklarovali metadáta našej aplikácie, rozhranie na zverejnenie a jeho implementáciu prostredníctvom , a .

The dubbo protokol je jedným z mnohých protokolov, ktoré rámec podporuje. Je postavený na vrchu neblokujúcej funkcie Java NIO a je to použitý predvolený protokol.

Podrobnejšie si to rozoberieme ďalej v tomto článku.

4.3. Register multicast - spotrebiteľ služieb

Všeobecne platí, že spotrebiteľ musí určiť rozhranie, ktoré má vyvolať, a adresu vzdialenej služby, a to je pre spotrebiteľa presne potrebné:

Teraz je všetko nastavené, pozrime sa, ako fungujú v akcii:

public class MulticastRegistryTest {@Before public void initRemote () {ClassPathXmlApplicationContext remoteContext = new ClassPathXmlApplicationContext ("multicast / provider-app.xml"); remoteContext.start (); } @Test public void givenProvider_whenConsumerSaysHi_thenGotResponse () {ClassPathXmlApplicationContext localContext = nový ClassPathXmlApplicationContext ("multicast / consumer-app.xml"); localContext.start (); GreetingsService greetingsService = (GreetingsService) localContext.getBean ("greetingsService"); Reťazec hiMessage = greetingsService.sayHi ("baeldung"); assertNotNull (hiMessage); assertEquals ("ahoj, baeldung", hiMessage); }}

Keď poskytovateľ remoteContext spustí, Dubbo sa automaticky načíta ZdravímSlužba a zaregistrujte ho do daného registra. V tomto prípade ide o register multicast.

Spotrebiteľ sa prihlási na odber multicastového registra a vytvorí si proxy servera ZdravímSlužba v kontexte. Keď náš miestny klient vyvolá povedz ahoj metóda, je to transparentné vyvolanie vzdialenej služby.

Zmienili sme sa, že register je voliteľný, čo znamená, že spotrebiteľ sa môže pripojiť priamo k poskytovateľovi prostredníctvom odkrytého portu:

V zásade je postup podobný tradičnej webovej službe, ale Dubbo to robí jednoduchým, jednoduchým a ľahkým.

4.4. Jednoduchý register

Upozorňujeme, že pri použití „neviditeľného“ registra viacsmerového vysielania nie je služba registra samostatná. Je to však použiteľné iba pre obmedzenú miestnu sieť.

Na výslovné nastavenie spravovateľného registra môžeme použiť a SimpleRegistryService.

Po načítaní nasledujúcej konfigurácie fazule do jarného kontextu sa spustí jednoduchá služba registra:

Všimnite si, že SimpleRegistryService trieda nie je v artefakte obsiahnutá, preto sme zdrojový kód skopírovali priamo z úložiska Github.

Potom upravíme konfiguráciu registra poskytovateľa a spotrebiteľa:

SimpleRegistryService pri testovaní možno použiť ako samostatný register, neodporúča sa však používať ho v produkčnom prostredí.

4.5. Konfigurácia Java

Podporovaná je aj konfigurácia pomocou Java API, súboru vlastností a anotácií. Súbor vlastností a anotácie sú však použiteľné iba v prípade, že naša architektúra nie je príliš zložitá.

Pozrime sa, ako je možné naše predchádzajúce konfigurácie XML pre multicastový register previesť do konfigurácie API. Najskôr je poskytovateľ nastavený takto:

ApplicationConfig application = nový ApplicationConfig (); application.setName ("poskytovateľ ukážky"); application.setVersion ("1.0"); RegistryConfig registryConfig = nový RegistryConfig (); registryConfig.setAddress ("multicast: //224.1.1.1: 9090"); ServiceConfig service = new ServiceConfig (); service.setApplication (aplikácia); service.setRegistry (registryConfig); service.setInterface (GreetingsService.class); service.setRef (nový GreetingsServiceImpl ()); service.export ();

Teraz, keď je služba už sprístupnená prostredníctvom multicastového registra, spotrebujme ju v lokálnom klientovi:

ApplicationConfig application = nový ApplicationConfig (); application.setName ("demo-spotrebiteľ"); application.setVersion ("1.0"); RegistryConfig registryConfig = nový RegistryConfig (); registryConfig.setAddress ("multicast: //224.1.1.1: 9090"); ReferenceConfig reference = nový ReferenceConfig (); reference.setApplication (aplikácia); reference.setRegistry (registryConfig); reference.setInterface (GreetingsService.class); GreetingsService greetingsService = reference.get (); Reťazec hiMessage = greetingsService.sayHi ("baeldung");

Aj keď úryvok vyššie funguje ako kúzlo ako predchádzajúci príklad konfigurácie XML, je o niečo triviálnejší. Pokiaľ máme v úmysle plne využívať Dubbo, mala by byť zatiaľ prvá voľba konfigurácia XML.

5. Podpora protokolu

Rámec podporuje viac protokolov vrátane dubbo, RMI, hesián, HTTP, webová služba, šetrnosť, memcached a redis. Väčšina protokolov vyzerá dobre, až na dubbo. Pozrime sa, čo je nové v tomto protokole.

The dubbo protokol udržuje trvalé spojenie medzi poskytovateľmi a spotrebiteľmi. Dlhé pripojenie a neblokujúca sieťová komunikácia NIO majú za následok pomerne vysoký výkon pri prenose dátových paketov malého rozsahu (<100 kB).

Existuje niekoľko konfigurovateľných vlastností, napríklad port, počet pripojení na jedného spotrebiteľa, maximálne akceptované pripojenia atď.

Dubbo tiež podporuje sprístupnenie služieb prostredníctvom rôznych protokolov naraz:

A áno, môžeme vystaviť rôzne služby pomocou rôznych protokolov, ako je uvedené v úryvku vyššie. Konfigurovateľné sú aj podkladové transportéry, implementácie serializácie a ďalšie bežné vlastnosti týkajúce sa sietí.

6. Ukladanie výsledkov do pamäte cache

Na urýchlenie prístupu k horúcim údajom je podporované natívne vzdialené ukladanie výsledkov. Je to také jednoduché ako pridať atribút medzipamäte k odkazu fazule:

Tu sme nakonfigurovali najmenej naposledy použitú vyrovnávaciu pamäť. Na overenie správania pri ukladaní do pamäte cache sa trochu zmeníme v predchádzajúcej štandardnej implementácii (nazvime ju „špeciálna implementácia“):

verejná trieda GreetingsServiceSpecialImpl implementuje GreetingsService {@Override public String sayHi (názov reťazca) {try {SECONDS.sleep (5); } catch (Výnimka ignorovaná) {} návrat "ahoj," + meno; }}

Po spustení poskytovateľa môžeme na strane spotrebiteľa overiť, či je výsledok uložený do pamäti pri viacnásobnom vyvolaní:

@Test public void givenProvider_whenConsumerSaysHi_thenGotResponse () {ClassPathXmlApplicationContext localContext = nový ClassPathXmlApplicationContext ("multicast / consumer-app.xml"); localContext.start (); GreetingsService greetingsService = (GreetingsService) localContext.getBean ("greetingsService"); dlho predtým = System.currentTimeMillis (); Reťazec hiMessage = greetingsService.sayHi ("baeldung"); long timeElapsed = System.currentTimeMillis () - predtým; assertTrue (timeElapsed> 5000); assertNotNull (hiMessage); assertEquals ("ahoj, baeldung", hiMessage); before = System.currentTimeMillis (); hiMessage = greetingsService.sayHi ("baeldung"); timeElapsed = System.currentTimeMillis () - predtým; assertTrue (timeElapsed <1000); assertNotNull (hiMessage); assertEquals ("ahoj, baeldung", hiMessage); }

Tu sa spotrebiteľ odvoláva na implementáciu špeciálnej služby, takže dokončenie vyvolania trvalo prvýkrát viac ako 5 sekúnd. Keď opäť privoláme, povedz ahoj metóda sa dokončí takmer okamžite, pretože výsledok sa vráti z medzipamäte.

Pamätajte, že lokálna medzipamäť vlákna a JCache sú tiež podporované.

7. Podpora klastrov

Spoločnosť Dubbo nám pomáha slobodne rozširovať naše služby vďaka schopnosti vyvážiť zaťaženie a niekoľkým stratégiám odolnosti proti chybám. Tu predpokladajme, že máme Zookeeper ako náš register na správu služieb v klastri. Poskytovatelia môžu zaregistrovať svoje služby v aplikácii Zookeeper takto:

Upozorňujeme, že tieto ďalšie závislosti potrebujeme v POM:

 org.apache.zookeeper zookeeper 3.4.11 com.101tec zkclient 0,10 

Najnovšie verzie servera ošetrovateľ v zoo závislosť a zkclient nájdete tu a tu.

7.1. Rozdelenie výkonu

V súčasnosti rámec podporuje niekoľko stratégií vyrovnávania zaťaženia:

  • náhodný
  • každý s každým
  • najmenej aktívny
  • konzistentný hash.

V nasledujúcom príklade máme dve implementácie služieb ako poskytovatelia v klastri. Žiadosti sú smerované pomocou prístupu „každý s každým“.

Najskôr nastavíme poskytovateľov služieb:

@Before public void initRemote () {ExecutorService executorService = Executors.newFixedThreadPool (2); executorService.submit (() -> {ClassPathXmlApplicationContext remoteContext = nový ClassPathXmlApplicationContext ("cluster / provider-app-default.xml"); remoteContext.start ();}); executorService.submit (() -> {ClassPathXmlApplicationContext backupRemoteContext = nový ClassPathXmlApplicationContext ("cluster / provider-app-special.xml"); backupRemoteContext.start ();}); }

Teraz máme štandardného „rýchleho poskytovateľa“, ktorý okamžite reaguje, a špeciálneho „pomalého poskytovateľa“, ktorý spí po dobu 5 sekúnd na každú žiadosť.

Po šiestom spustení so stratégiou round-robin očakávame, že priemerný čas odozvy bude minimálne 2,5 sekundy:

@Test public void givenProviderCluster_whenConsumerSaysHi_thenResponseBalanced () {ClassPathXmlApplicationContext localContext = nový ClassPathXmlApplicationContext ("cluster / consumer-app-lb.xml"); localContext.start (); GreetingsService greetingsService = (GreetingsService) localContext.getBean ("greetingsService"); Zoznam elapseList = nový ArrayList (6); pre (int i = 0; i e). priemer (); assertTrue (avgElapse.isPresent ()); assertTrue (avgElapse.getAsDouble ()> 2500.0); }

Okrem toho je prijaté dynamické vyrovnávanie zaťaženia. Nasledujúci príklad ukazuje, že so stratégiou opakovania si spotrebiteľ automaticky zvolí nového poskytovateľa služieb ako kandidáta, keď sa nový poskytovateľ pripojí k internetu.

„Pomalý poskytovateľ“ je zaregistrovaný o 2 sekundy neskôr po spustení systému:

@Before public void initRemote () {ExecutorService executorService = Executors.newFixedThreadPool (2); executorService.submit (() -> {ClassPathXmlApplicationContext remoteContext = nový ClassPathXmlApplicationContext ("cluster / provider-app-default.xml"); remoteContext.start ();}); executorService.submit (() -> {SECONDS.sleep (2); ClassPathXmlApplicationContext backupRemoteContext = new ClassPathXmlApplicationContext ("cluster / provider-app-special.xml"); backupRemoteContext.start (); return null;}); }

Spotrebiteľ vyvolá vzdialenú službu raz za sekundu. Po šiestom spustení očakávame, že priemerný čas odozvy bude vyšší ako 1,6 sekundy:

@Test public void givenProviderCluster_whenConsumerSaysHi_thenResponseBalanced () hodí InterruptedException {ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext ("cluster / consumer-app-lb.xml"); localContext.start (); GreetingsService greetingsService = (GreetingsService) localContext.getBean ("greetingsService"); Zoznam elapseList = nový ArrayList (6); pre (int i = 0; i e). priemer (); assertTrue (avgElapse.isPresent ()); assertTrue (avgElapse.getAsDouble ()> 1666.0); }

Upozorňujeme, že nástroj na vyrovnávanie zaťaženia je možné nakonfigurovať na strane spotrebiteľa aj na strane poskytovateľa. Tu je príklad konfigurácie na strane spotrebiteľa:

7.2. Odolnosť proti chybám

Dubbo podporuje niekoľko stratégií odolnosti proti chybám, medzi ktoré patrí:

  • zlyhanie
  • bezpečný proti zlyhaniu
  • rýchlo zlyhať
  • zlyhanie
  • rozdvojenie.

V prípade zlyhania, keď zlyhá jeden poskytovateľ, môže spotrebiteľ vyskúšať s niektorými ďalšími poskytovateľmi služieb v klastri.

Stratégie odolnosti proti poruchám sú pre poskytovateľov služieb nakonfigurované takto:

Na demonštráciu zlyhania služby v akcii vytvorme implementáciu zlyhania služby ZdravímSlužba:

verejná trieda GreetingsFailoverServiceImpl implementuje GreetingsService {@Override public String sayHi (názov reťazca) {return "ahoj, zlyhanie" + meno; }}

Môžeme si spomenúť na našu špeciálnu implementáciu služieb ZdravímSlužbaSpeciálneImpl spí 5 sekúnd pre každú požiadavku.

Keď sa akákoľvek odpoveď, ktorá trvá dlhšie ako 2 sekundy, považuje za zlyhanie požiadavky pre spotrebiteľa, máme scenár obnovenia prevádzky:

Po spustení dvoch poskytovateľov môžeme overiť správanie pri zlyhaní pomocou nasledujúceho úryvku:

@Test public void whenConsumerSaysHi_thenGotFailoverResponse () {ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext ("cluster / consumer-app-failtest.xml"); localContext.start (); GreetingsService greetingsService = (GreetingsService) localContext.getBean ("greetingsService"); Reťazec hiMessage = greetingsService.sayHi ("baeldung"); assertNotNull (hiMessage); assertEquals ("hi, failover baeldung", hiMessage); }

8. Zhrnutie

V tomto tutoriáli sme si trochu zahryzli do Dubba. Väčšina používateľov je priťahovaná svojou jednoduchosťou a bohatými a výkonnými funkciami.

Okrem toho, čo sme predstavili v tomto článku, má rámec niekoľko funkcií, ktoré ešte treba preskúmať, napríklad overenie parametrov, notifikácie a spätné volania, všeobecná implementácia a referencia, vzdialené zoskupenie a zlúčenie výsledkov, aktualizácia služby a spätná kompatibilita. zopár.

Celú implementáciu nájdete ako vždy na Githube.


$config[zx-auto] not found$config[zx-overlay] not found