17 odabranih Dubbo pitanja za intervju👍
Sadržaj
- Šta je Dubbo? A šta je RPC?
- 2. Šta može Dubbo?
- Možeš li da opišeš ukupni proces poziva u Dubbo-u?
- Reci koje protokole podržava Dubbo, kao i primenu scenarija, prednosti i mane svakog
- Koje obrasce dizajna Dubbo koristi?
- Šta ako usluga koju pruža provider u Dubbo-u ima više verzija?
- Kako izgleda proces izlaganja usluge?
- Kako izgleda proces referenciranja usluge?
- Koja sve registra centri (registry) postoje za Dubbo?
- Pričajmo o Dubbo SPI mehanizmu?
- Koja je razlika između Dubbo SPI i Java SPI?
- Koje strategije balansiranja opterećenja postoje?
- Koji načini klaster tolerancije na greške postoje?
- Pričaj o Dubbo slojevima?
- Po kom principu provider usluge realizuje izbacivanje neispravnih čvorova?
- Zašto se komunikacija vrši preko proxy objekta?
- Kako dizajnirati RPC okvir?
1. Šta je Dubbo? A šta je RPC?
Dubbo je okvir za distribuirane usluge, posvećen pružanju visoko-performantnog i transparentnog rešenja za RPC poziv udaljenih usluga, kao i SOA rešenja za upravljanje uslugama.
RPC (Remote Procedure Call) — poziv udaljene procedure; to je protokol koji putem mreže zahteva uslugu od programa na udaljenom računaru, a da ne zahteva poznavanje donjih slojeva mrežne tehnologije. RPC protokol pretpostavlja postojanje određenih transportnih protokola, kao što su TCP ili UDP, koji nose podatke između programa koji komuniciraju. U OSI mrežnom modelu, RPC prelazi sloj transporta i sloj aplikacije. RPC olakšava razvoj aplikacija koje obuhvataju više mrežno distribuiranih programa. RPC koristi model klijent/server. Program koji zahteva je klijent, a program koji pruža uslugu je server. Najpre klijentski proces poziva šalje informaciju o pozivu sa argumentima procesu usluge, a zatim čeka na odgovor. Na strani servera proces ostaje u stanju spavanja dok ne stigne informacija o pozivu. Kada informacija o pozivu stigne, server prikupi argumente procesa, izračuna rezultat, pošalje odgovor, a zatim čeka sledeći poziv. Na kraju klijentski proces poziva prima odgovor, dobija rezultat procesa i nastavlja izvršavanje. Postoji više RPC modova i implementacija.

Objasnimo to jezikom koji je lako razumeti: udaljeni poziv je proces u kome lokalna mašina pozove metodu na udaljenoj mašini, a udaljena mašina vrati rezultat.
Zašto se to radi?
Glavni razlog je taj što performanse jedne mašine više ne mogu da nas zadovolje; u eri eksplozivnog rasta saobraćaja samo više servera može da nosi današnji sistem korisnika,
a pod takvim sistemom usluge postaju sve brojnije i postepeno se evoluiralo u današnje mikro-servisne RPC okvire.
2. Šta može Dubbo?
Jezgarne funkcije Dubba uglavnom obuhvataju:

Udaljena komunikacija: dubbo-remoting modul, pruža apstraktno uvezivanje za više NIO okvira zasnovanih na dugim vezama, uključujući više modela niti, serijalizaciju, kao i način razmene informacija „zahtev-odgovor".
Tolerancija klastera na greške: pruža transparentan poziv udaljene procedure zasnovan na metodi interfejsa, uključujući podršku za više protokola, kao i softversko balansiranje opterećenja, toleranciju na greške, adresno rutiranje, dinamičku konfiguraciju i drugu podršku klastera.
Automatsko otkrivanje: na osnovu servisa direktorijuma registra centra, omogućava potrošaču usluge da dinamički pronalazi pružaoca usluge, čini adresu transparentnom i omogućava pružaocu usluge da glatko dodaje ili uklanja mašine.
3. Možeš li da opišeš ukupni proces poziva u Dubbo-u?
Dijagram procesa poziva:

- Proxy drži jedan Invoker objekat i koristi Invoker za poziv.
- Zatim putem Cluster-a vrši balansiranje opterećenja i toleranciju na greške, uz ponovni pokušaj pri neuspehu.
- Poziva Directory da dobavi listu Invoker-a udaljene usluge.
- Balansiranje opterećenja.
- Ako je korisnik konfigurisao pravila rutiranja, filtrira se dobijena Invoker lista prema pravilima rutiranja.
- Ako korisnik nije konfigurisao pravila rutiranja ili ih je konfigurisao a čvorova i dalje ima mnogo, koristi se LoadBalance metoda za balansiranje opterećenja i bira se jedan Invoker koji se može pozvati.
- Prolazi kroz lanac filtera, obično za obradu konteksta, ograničavanje protoka, brojanje itd.
- Koristi Client za prenos podataka.
- Konstrukcija privatnog protokola (Codec).
- Serijalizacija.
- Server primi ovaj Request zahtev i dodeli ga u ThreadPool na obradu.
- Server obrađuje te Request-ove.
- Prema zahtevu pronalazi odgovarajući Exporter.
- Zatim prolazi kroz lanac filtera na strani pružaoca usluge.
- Onda pronalazi implementaciju interfejsa i stvarno poziva, pa vraća rezultat zahteva.
4. Reci koje protokole podržava Dubbo, kao i primenu scenarija, prednosti i mane svakog

- 1. dubbo — jedna duga veza i NIO asinhrona komunikacija, pogodno za pozive usluga sa velikom konkurentnošću i malom količinom podataka, i kada je broj potrošača znatno veći od broj pružalaca. Transportni protokol je TCP, asinhrono, Hessian serijalizacija.
- 2. rmi — koristi implementaciju standardnog JDK rmi protokola; argumenti prenosa i objekti povratnih vrednosti moraju da implementiraju Serializable interfejs; koristi standardni Java mehanizam serijalizacije; koristi blokirajuću kratku vezu; veličina prenosa paketa je mešovita; broj potrošača i pružalaca je približno jednak; može da prenosi fajlove; transportni protokol je TCP. Više kratkih veza, TCP transportni protokol, sinhroni prenos; pogodno za uobičajene pozive udaljenih usluga i međusobnu operaciju sa rmi. Zavisno od verzije paketa Common-Collections, Java serijalizacija ima bezbednosne propuste.
- 3. webservice — protokol poziva udaljene procedure zasnovan na WebService-u, integriše CXF implementaciju, pruža međuoperabilnost sa izvornim WebService-om. Više kratkih veza, zasnovano na HTTP transportu, sinhroni prenos; pogodno za integraciju sistema i pozive između različitih jezika.
- 4. http — protokol poziva udaljene procedure zasnovan na slanju HTTP formi, koristi Spring-ov HttpInvoke. Više kratkih veza, transportni protokol HTTP, veličina ulaznih parametara je mešovita; broj pružalaca veći od broj potrošača; potrebno za pozive iz aplikacija i pregledačkog JS-a.
- 5. hessian — integriše Hessian uslugu, zasnovano na HTTP komunikaciji, koristi Servlet za izlaganje usluge; podrazumevana implementacija kada Dubbo ugradi Jetty kao server; pruža međuoperabilnost sa Hessian uslugom. Više kratkih veza, sinhroni HTTP prenos, Hessian serijalizacija; ulazni parametri su relativno veliki; broj pružalaca veći od broj potrošača; pružaoci su pod većim pritiskom; može da prenosi fajlove.
- 6. memcache — RPC protokol zasnovan na memcached implementaciji.
- 7. redis — RPC protokol zasnovan na redis implementaciji.
5. Koje obrasce dizajna Dubbo koristi?

Obrazac lanca odgovornosti:
Obrazac lanca odgovornosti u Dubbo-u igra ključnu ulogu, poput kostura Dubbo okvira. Lanac poziva u Dubbo-u organizovan je tako što je povezan obrascem lanca odgovornosti. Svaki čvor u lancu implementira Filter interfejs, a zatim ProtocolFilterWrapper povezuje sve Filter-e u lanac. Mnoge funkcije Dubba implementirane su kroz Filter ekstenzije, kao što su nadzor, logovanje, keširanje, bezbednost, telnet, pa i sam RPC.
Obrazac posmatrača:
Najtipičniji primer upotrebe obrasca posmatrača u Dubbo-u je RegistryService. Pri inicijalizaciji potrošač poziva subscribe metodu i registruje posmatrača; ako se lista adresa usluge koju posmatrač referencira promeni, putem NotifyListener-a se obaveštava potrošač. Pored toga, InvokerListener i ExporterListener u Dubbo-u takođe implementiraju obrazac posmatrača — dovoljno je implementirati taj interfejs i registrovati se, pa primalac može primiti obaveštenja o pozivu refer na strani consumer-a i pozivu export na strani provider-a.
Obrazac dekoratora:
U Dubbo-u se obrazac dekoratora takođe koristi u velikoj meri. Na primer, klasa ProtocolFilterWrapper je dekoracija klase Protocol. U export i refer metodama, u sprezi sa obrascem lanca odgovornosti, Filter-i se sastavljaju u lanac odgovornosti, ostvarujući dekoraciju funkcionalnosti Protocol-a. Ostali primeri su ProtocolListenerWrapper, ListenerInvokerWrapper, InvokerWrapper itd.
Obrazac fabričke metode:
Implementacija CacheFactory koristi obrazac fabričke metode. CacheFactory interfejs definiše getCache metodu, a zatim se definiše apstraktna klasa AbstractCacheFactory koja implementira CacheFactory i izdvaja metodu createCache koja zaista kreira cache, pri čemu je ona postavljena kao apstraktna metoda. Tako se stvarni posao kreiranja cache-a prepušta konkretnim podklasama.
Obrazac apstraktne fabrike:
ProxyFactory i njegove podklase tipičan su primer obrasca apstraktne fabrike u Dubbo-u. ProxyFactory pruža dve metode koje služe za proizvodnju Proxy-ja i Invoker-a (ove dve metode izgledaju pomelo kontradiktorno, jer getProxy metoda zahteva Invoker objekat, a getInvoker metoda zahteva Proxy objekat, što izgleda kao ciklična zavisnost, ali se zapravo dve metode koriste u različitim scenarijima). AbstractProxyFactory implementira ProxyFactory interfejs i služi kao apstraktna nadklasa konkretnih klasa implementacija. Zatim su definisane dve konkretne klase, JdkProxyFactory i JavassistProxyFactory, koje proizvode Proxy i Invoker zasnovane na jdk mehanizmu proxy-ja, odnosno na javassist mehanizmu proxy-ja.
Obrazac adaptera:
Kako bi korisnicima omogućio da prema svojim potrebama izaberu komponentu za logovanje, Dubbo je definisao sopstveni Logger interfejs i za uobičajene komponente za logovanje (uključujući jcl, jdk, log4j, slf4j) pružio odgovarajuće adaptore. Uz to, pomoću jednostavnog obrasca fabrike pruža se LoggerFactory, pa klijent može da kreira apstraktni Dubbo prilagođeni Logger bez brige o tome koja se komponenta za logovanje zapravo koristi. Pri inicijalizaciji LoggerFactory, klijent postavljanjem sistemske varijable bira komponentu za logovanje koju koristi, što pruža veliku fleksibilnost.
Obrazac proxy-ja:
Dubbo consumer koristi klasu Proxy za kreiranje lokalnog proxy-ja udaljene usluge; lokalni proxy implementira isti interfejs kao i udaljena usluga i sakriva detalje mrežne komunikacije, pa korisnik pri korišćenju lokalnog proxy-ja ima osećaj kao da koristi lokalnu uslugu.
6. Šta ako usluga koju pruža provider u Dubbo-u ima više verzija?
Može se direktno kontrolisati više verzija preko verzije (version) u Dubbo konfiguraciji.
Na primer:
<dubbo:service interface="com.xxxx.rent.service.IDemoService" ref="iDemoServiceFirst" version="1.0.0"/>
<dubbo:service interface="com.xxxx.rent.service.IDemoService" ref="iDemoServiceSecond" version="1.0.1"/>Stara verzija version=1.0.0, nova verzija version=1.0.1.
7. Kako izgleda proces izlaganja usluge?

ServiceConfig-om se raščlanjuju tagovi, kreira se dubbo parser tagova koji parsira dubbo tagove; nakon kreiranja kontejnera, okida se ContextRefreshEvent događaj koji započinje izlaganje usluge.
putem metode proxyFactory.getInvoker, uz pomoć javassist-a ili JdkProxyFactory-ja za dinamički proxy, interfejs izložene usluge se umotava u Invoker objekat, koji sadrži informacije o objektu metode koju treba izvršiti i konkretnu URL adresu.
Zatim kroz implementaciju DubboProtocol umotani invoker se konvertuje u exporter.
Onda se pokreće server, koji sluša na portu.
Na kraju RegistryProtocol čuva mapiranje između URL adrese i invoker-a, a istovremeno vrši registraciju u registar centar.

8. Kako izgleda proces referenciranja usluge?
Klijent najpre na osnovu informacija iz config fajla iz registra centra pretplaćuje se na uslugu; prvi put se sve kešira lokalno, a naknadna ažuriranja se prate i dinamički ažuriraju lokalno.
Zatim DubboProtocol prema adresi i informacijama o interfejsu provider-a povezuje se na server, otvara klijent (client), a zatim kreira invoker.
Nakon toga se iz invoker-a generiše proxy objekat za interfejs usluge; taj proxy objekat služi za poziv provider-a na daljinu, čime se referenciranje usluge završava.

9. Koja sve registra centri postoje za Dubbo?

Zookeeper, Redis, Multicast, Simple itd. mogu poslužiti kao registar centar za Dubbo.
10. Pričajmo o Dubbo SPI mehanizmu?
SPI (Service Provider Interface) je mehanizam za otkrivanje usluga; suština je da se implementaciona klasa interfejsa upisuje u konfiguraciju, a prilikom učitavanja usluge se čita konfiguracioni fajl i učitava implementaciona klasa, čime se u toku rada dinamički pomaže interfejsu da zameni implementacionu klasu.
Dubbo SPI je zapravo vrsta poboljšanja Java SPI: pored učitavanja implementacionih klasa po potrebi, dodao je IOC i AOP karakteristike, kao i mehanizam samoadaptivnog proširenja.
SPI se u Dubbo-u koristi na mnogo mesta, uključujući proširenje protokola, proširenje klastera, proširenje rutiranja, proširenje serijalizacije itd.
Dubbo konfiguraciju fajl direktorijuma deli na tri kategorije.
- Direktorijum META-INF/services/: SPI konfiguracioni fajlovi u ovom direktorijumu služe za kompatibilnost sa Java SPI.
- Direktorijum META-INF/dubbo/: ovaj direktorijum čuva korisnički definisane SPI konfiguracione fajlove.
key=com.xxx.xxx- Direktorijum META-INF/dubbo/internal/: ovaj direktorijum čuva SPI konfiguracione fajlove za internu upotrebu u Dubbo-u.
11. Koja je razlika između Dubbo SPI i Java SPI?

Java SPI
- Java SPI prilikom traženja implementacione klase ekstenzije prelazi SPI konfiguracioni fajl i instancira sve implementacione klase.
Dubbo SPI
- Za proširenje Dubba nije potrebno menjati izvorni kôd Dubba.
- Lenjo učitavanje — može se učitati samo ono proširenje koje želimo.
- Dodata je podrška za IOC i AOP ekstenzionih tačaka; jedna ekstenziona tačka može direktno putem setter-a injektovati druge ekstenzione tačke.
- Dubbo-ov mehanizam proširenja dobro podržava IoC kontejnere trećih strana, podrazumevano podržava Spring Bean.
12. Koje strategije balansiranja opterećenja postoje?
1. Slučajno sa težinama: na primer, imamo tri servera [A, B, C], postavimo im težine [4, 5, 6], a zatim ova tri broja raširimo na horizontalnu liniju, sa zbirom 15.
Zatim generišemo slučajan broj u opsegu do 15: 0 ~ 4 je server A, 4 ~ 9 je server B, 9 ~ 15 je server C.

2. Najmanji broj aktivnih: svaki pružalac usluge odgovara jednom aktivnom broju active; u početnom stanju svi pružaoci usluge imaju aktivni broj 0. Po prijemu svakog zahteva aktivni broj se povećava za 1, a nakon završetka zahteva aktivni broj se smanjuje za 1. Nakon što usluga radi izvesno vreme, pružaoci usluge sa boljim performansama brže obrađuju zahteve, pa im aktivni broj i brže opada; takvi pružaoci usluge mogu prioritetno da dobiju nove zahteve usluge.

3. Konzistentni hash:
- Najpre se izračuna hash vrednost memcached servera (čvora) i postavi na krug (continuum) od 0 do 2 na 32.
- Zatim se na isti način izračuna hash vrednost ključa podataka koji se čuvaju i mapira na isti krug.
- Onda se kreće od pozicije na koju su podaci mapirani u smeru kazaljke na satu i traži prvi server na koji se podaci čuvaju. Ako se ni nakon 2 na 32 ne pronađe server, podaci se čuvaju na prvi memcached server.

4. Round-robin sa težinama: na primer, imamo tri servera [A, B, C], postavimo im težine [4, 5, 6]; ako ukupno ima 15 zahteva, onda će 4 pasti na server A, 5 na server B, a 6 na server C.

13. Koji načini klaster tolerancije na greške postoje?
Failover Cluster — automatski prebacivanje pri neuspehu: podrazumevani Dubbo režim tolerancije; kada poziv ne uspe automatski se prebacuje na drugi dostupan čvor. Broj ponovnih pokušaja i vremenski razmak mogu se konfigurisati prilikom referenciranja usluge; podrazumevani broj ponovnih pokušaja je 1, odnosno poziva se samo jednom.
Failback Cluster — automatski oporavak pri neuspehu: kada poziv ne uspe, zabeleži se log i informacije o pozivu, a zatim consumer-u vrati prazan rezultat, a zakazanim zadatkom svakih 5 sekundi ponovo pokušava neuspele pozive.
Failfast Cluster — brzi neuspeh: poziva se samo jednom, a nakon neuspeha odmah baca izuzetak.
Failsafe Cluster — bezbedan pri neuspehu: ako pri pozivu nastane izuzetak, zabeleži se log bez bacanja, pa se vraća prazan rezultat.
Forking Cluster — paralelan poziv više pružalaca usluge: kroz bazen niti kreira više niti koje konkurentno pozivaju više provider-a; rezultati se čuvaju u blokirajući red; čim jedan provider uspešno vrati rezultat, odmah se vraća rezultat.
Broadcast Cluster — režim broadcast-a: poziva se svaki provider jedan po jedan; ako jedan prijavi grešku, nakon završetka ciklusa poziva baca se izuzetak.
14. Pričaj o Dubbo slojevima?
Dijagram slojeva:

Sa šireg gledišta, Dubbo je podeljen na tri sloja:
- business — sloj poslovne logike koji sami obezbeđujemo interfejs i implementaciju, kao i deo konfiguracionih informacija.
- RPC — sloj koji je jezgro stvarnog RPC poziva, obuhvata čitav proces RPC poziva, balansiranje opterećenja, toleranciju klastera na greške, proxy.
- remoting — obuhvata mrežni transportni protokol i konverziju podataka.
Slojevi Service i Config mogu se smatrati API slojem, namenjenim prvenstveno korisnicima API-ja — korisniku je dovoljno da podesi konfiguraciju i napiše poslovni kôd.
Svi naredni slojevi su SPI sloj, namenjen prvenstveno onima koji proširuju, uglavnom za sekundarni razvoj Dubba i proširenje funkcionalnosti.
Na još finijem nivou, to je model od 10 slojeva prikazan na slici.
15. Po kom principu provider usluge realizuje izbacivanje neispravnih čvorova?
Izbacivanje neispravnih usluga zasnovano je na principu privremenog (ephemeral) čvora Zookeeper-a.
Čvorovi u Zookeeper-u imaju životni ciklus; specifičan životni ciklus zavisi od tipa čvora. Čvorovi se uglavnom dele na trajne čvorove (Persistent) i privremene čvorove (Ephemeral).
16. Zašto se komunikacija vrši preko proxy objekta?

U suštini, razlog je da se detalji poziva enkapsuliraju — poziv udaljene metode postaje isto tako jednostavan kao i poziv lokalne metode; uz to se mogu raditi i druga poboljšanja, kao što su balansiranje opterećenja, mehanizam tolerancije na greške, operacije filtriranja i statistika podataka o pozivima.
17. Kako dizajnirati RPC okvir?
Za ovo pitanje, suština provere je razumevanje RPC okvira; jedan zreo RPC okvir može da ostvari koje funkcionalnosti — zapravo, nakon što pregledamo jedan ili dva RPC okvira, na ovo pitanje možemo odgovoriti prilično temeljno. Hajde da navedemo primer.

Najpre nam je potreban registar centar koji upravlja informacijama o čvorovima potrošača i pružalaca, kako bi potrošači i pružaoci mogli da pretplaćuju i registruju usluge.
Kada imamo registar centar, možda će postojati mnogo provider čvorova, pa ćemo sigurno imati modul za balansiranje opterećenja zadužen za pozive čvorova; korisnički definisana pravila rutiranja mogu biti dodatna tačka optimizacije.
Konkretan poziv će sigurno zahtevati komunikacioni protokol, pa je potreban modul koji obuhvata komunikacioni protokol, a za mrežni prenos treba razmotriti i serijalizaciju.
Šta raditi kada poziv ne uspe? Zato nam je potreban i modul za toleranciju na greške koji je zadužen za obradu situacija pri neuspehu.
U stvari, kada se ovo završi, osnovni model je već postavljen; možemo imati i dodatne tačke optimizacije, kao što su nadzor podataka o zahtevima, obrada konfiguracionih informacija, obrada log informacija itd.
Ovo je zapravo opšta ideja prilično osnovnog RPC okvira — da li ste uhvatili poentu?
Referentni link: https://mp.weixin.qq.com/s?__biz=MzkwODE5ODM0Ng==&mid=2247491592&idx=1&sn=454ae3d6a661a1eb63ffbad767ccb479&chksm=c0cf08adf7b881bbfd7d2a2ad150e7621756ccc06a6ffacd52833e7f4b84d5d01e16e5a6770f&scene=27#wechat_redirect, Autor: moon-ov tehnološki blog, Priredio: Chenmo Wang Er
