Așteptați până când vor afla cât de rapide sunt apelurile funcționale în proces decât RPC-urile.

jar-urile

Folosesc un cadru la Google care se bazează pe microservicii și permite compunerea microservicilor într-un ansamblu. În cadrul unui ansamblu, apelurile între servicii se fac în proces; dacă apelezi un serviciu într-un alt ansamblu, acesta trebuie să facă un RPC.

Mecanica dacă este vorba de un apel local sau de un RPC este tratată la nivelul cadrului. Acest lucru face ca împărțirea unui serviciu în propriul său ansamblu să fie o sarcină simplă (nu trebuie să actualizați niciun cod, ci doar configurarea; acest lucru poate fi gestionat de SRE).

Seamănă mult cu OTP.

În Java-land, puteți, de asemenea, să aveți clientul și serviciul dvs. să utilizeze aceeași interfață. Doar injectați diferite implementări pentru local și la distanță.

Odată ce v-ați confruntat cu probleme de a genera automat lipici între interfața locală și obiectul la distanță, devine simplu să interpuneți alte lucruri utile - verificări de securitate, tranzacții dacă utilizați o bază de date relațională etc. Puteți chiar să aveți codul de lipici care să instanțeze leneș componentele serviciului, deci nu este nevoie să le încărcați până când un client nu face un apel.

Totuși, ți-ai dori un nume interesant. Extrem de legare Java? Autobuz Jet îmbunătățit? Excelentă Joy Bringer?

Sincer, dacă nu poți avea încredere în dezvoltatorii tăi să nu facă o mizerie într-un monolit, nu poți avea încredere în ei să nu facă o mizerie distribuită cu microservicii.

Ambele modele arhitecturale își au utilizările. Niciunul dintre ei nu vă va salva de dezvoltatorii răi.

M-aș putea înșela și în acest sens, dar îmi place microserviciul după ce proiectele ating o anumită dimensiune.

Cu un singur spațiu de memorie este ușor să parcurgi pur și simplu orice arhitectură pe care ar trebui să o urmezi.

Microserviciile nu rezolvă bile de noroi, dar pot îngreuna formarea și formarea mai ușoară a punctelor.

Nu este un panaceu, se pare că doar împingi complexitatea într-un alt loc.

Și nu, nu panaceu, doar un mod de gândire care cred că este util.

Sunt un mare fan al unui SOA bine conceput, dar acest lucru nu este blogabil în mod corespunzător aici în 2016.

Acum, OK, ecosistemului JVM îi lipsește un sistem de module bun în acest moment. Dar Java 9 o va remedia. Există, de asemenea, OSGi, deși nu știu prea multe despre asta.

Împingerea complexității pe comunicarea între proces și mașină va duce doar la niveluri mai ridicate de spaghete. Chiar crezi că aceiași oameni care ar construi un monolit prost ar face o treabă mai bună construind un sistem distribuit?

Nu vreau să fiu prea dogmatic; există cazuri de utilizare legitime pentru servicii. Sunt doar foarte sceptic cu privire la microservicii ca soluție pentru complexitate.

2017 va fi anul întoarcerii monolitului: „Cum am înlocuit 946 de microservicii cu un binar de rugină legat static de 10kB și cum nu ne-a salvat în mod extrem de lipsa noastră completă de ceva asemănător unui model de afaceri coerent”.

Acum că legea lui Moore se epuizează, ne putem aștepta în mod rezonabil să devină falsă în următorul deceniu. Împărțirea dintre cei care pot scrie doar cod și cei care pot proiecta în mod corespunzător sisteme software va deveni prea evidentă atunci.

Abordarea descrisă în acest articol este modul în care Java a fost conceput să funcționeze; dar apoi toată lumea a spus că aveți nevoie de un serviciu binar „autoexecutabil” pentru portabilitate. Introduceți vasul de grăsime, recipientele, straturile de orchestrație etc.

Serverele de aplicații JVM sunt cu siguranță calea de urmat dacă rulați o grămadă de Java. Dar atunci vă angajați să mențineți o grămadă de dependențe pe serverele dvs. de aplicații, așa că într-adevăr împingeți datoria tehnologiei în jos către operatorii dvs. care trebuie acum să se asigure că dependențele sunt sincronizate, serverele maven rulează și se actualizează corect, proxy-urile perforat pentru noi dependențe externe etc.

Jonathan: dacă ascultați, v-ați uitat la Maven ca sursă în loc de încărcare S3? Ce procent din dependențele dvs. este intern vs. extern? Obținem economii de spațiu de 10-20x datorită eliziei publice numai Maven.

EDIT: am lucrat la o tehnică similară și pentru JAR-urile executabile, care împărtășește aceleași numere și abordare generală de optimizare. Este un pic mai complicat, din moment ce vrem să păstrăm aceeași sintaxă „java -jar”, ​​deci necesită un pic de descărcare de clasă și conștientizarea corespunzătoare a clasificatorului în cod.

De fapt, încă producem JAR-uri executabile cu această abordare. Configurăm plugin-ul maven-jar pentru a construi classpath la momentul construirii și îl adăugăm ca intrare Class-Path la manifest. Aceasta este o intrare manifestă specială și la pornire, JVM adaugă automat aceste fișiere la clasa, astfel încât JAR-urile noastre subțiri sunt rulabile cu java -jar presupunând că dependențele sunt abandonate la locul potrivit. Slimfast-plugin citește configurația maven-jar-plugin pentru a vă asigura că generează căile potrivite pentru dependențe. Ajungem cu un JAR executabil și nu avem nicio afacere amuzantă cu runtime sau ClassLoader.

Tratați orice proiect open source produsul dvs. depinde de același mod în care ați plătit în numerar - stocați o copie în depozitul de coduri și faceți o copie de rezervă cu restul codului sursă.

- dacă lansarea aceleiași versiuni a fost modificată în amonte și doriți ca această modificare să fie preluată, oricum nu este o versiune repetabilă.

- dacă versiunea a fost modificată în amonte și nu doriți să o ridicați, configurați Arhiva pentru a eșua la o nepotrivire a sumelor de verificare [1].

- sau ca alternativă la aplicarea sumei de control, configurați repo-ul local ca intern în loc de proxy și gestionați-l singur [2].

Pentru RĂZBOI: într-un pas de construcție mvn:

- identificați dependențele candidate pentru a le exclude din RĂZBOI. Aceasta include un pas de filtrare pentru a menține dependențele interne în directorul WEB-INF.

- generați un manifest JSON al tuturor dependențelor excluse, inclusiv SHA-urile lor locale, și stocați manifestul în WEB-INF.

- copiați un script shell în noua Maven Archive (MAR) care știe cum să inverseze procesul de mai sus și să scoată un RĂZBOI

Apoi, în procesul nostru de construire, trecem în jurul fișierelor MAR până la momentul implementării, moment în care ne extindem înapoi într-un RĂZBOI și implementăm.

Ne-am uitat doar la implementarea MAR-urilor în sine, dar modul în care containerele noastre gestionează spațiul cache de fișiere a fost mai ușor să le rehidratăm înainte de implementare.

Pentru JAR-urile executabile: din nou, începem într-o fază de construire Maven și identificăm din nou dependențele de inclus vs. dependențele care trebuie excluse și preluate ulterior. Creăm un JAR complet nou care conține toate clasele în borcanul subțire construit de Maven (cred ca un JAR de referință, nu ca clase extinse). Apoi, grupăm toate JAR-urile incluse direct în JAR-ul țintă și scriem un manifest CSV care identifică ce dependențe externe erau necesare în timpul rulării. Copiem apoi un fișier .class brut fără dependențe [1] în JAR-ul țintă și scriem un manifest care identifică acea clasă drept clasa principală. Clasa respectivă este responsabilă pentru invocarea „mvn” prin execuția shell-ului pentru a încărca dependențe, construirea unui încărcător de clasă cu calea de clasă potrivită etc. și apoi predarea clasei principale originale.