reactive distributed applications with vert.x
TRANSCRIPT
REACTIVEDISTRIBUTEDSYSTEMSWITHVERT.X
CLEMENTESCOFFIERREDHAT
VERT.XISATOOLKITTOBUILDDISTRIBUTEDANDREACTIVESYSTEMS
ONTOPOFTHEJVMUSINGANASYNCHRONOUSNON-BLOCKING
DEVELOPMENTMODEL.
TOOLKITVert.xisaplainboringjarVert.xcomponentsareplainboringjarsYourapplicationdependsonthissetofjars(classpath,fat-jar,...)
DISTRIBUTED“Youknowyouhaveadistributed
systemwhenthecrashofacomputeryou'veneverheardsofstopsyou
fromgettinganyworkdone.”(LeslieLamport)
REACTIVESYSTEMSResponsive-theyrespondinanacceptabletimeElastic-theyscaleupanddownResilient-theyaredesignedtohandlefailuresgracefullyAsynchronous-theyinteractusingasyncmessages
http://www.reactivemanifesto.org/
REACTIVESYSTEMS!=REACTIVEPROGRAMMING
REACTIVESYSTEMS+REACTIVEPROGRAMMING
POLYGLOTVert.xapplicationscanbedevelopedusing
JavaGroovyRuby(JRuby)JavaScript(Nashorn)CeylonScalaKotlin
VERT.XAtoolkittobuilddistributedsystems
VERT.XBuilddistributedsystems:
DonothidethecomplexityFailureasfirst-classcitizenProvidethebuildingblocks,notanall-in-onesolution
WHATDOESVERT.XPROVIDE?TCP,UDP,HTTP1&2serversandclients(non-blocking)DNSclientClusteringEventbus(messaging)Distributeddatastructures(built-in)Load-balancing(built-in)Fail-overPluggableservicediscovery,circuit-breakerMetrics,Shell
REACTIVEBuildreactivedistributedsystems:
Responsive-fast,isabletohandlealargenumberofevents/connectionsElastic-scaleupanddownbyjuststartingandstoppingnodes,round-robinResilient-failureasfirst-classcitizen,fail-overAsynchronousmessage-passing-asynchronousandnon-blockingdevelopmentmodel
ASYNCHRONOUS&NON-BLOCKING
ASYNCHRONOUS&NON-BLOCKING// Synchronous development modelX x = doSomething(a, b);
// Asynchronous development model - callback variantdoSomething(a, b, // Params ar -> { // Last param is a Handler<AsyncResult<X>> // Result handler });
// Asynchronous development model - future variantFuture<X> future = doSomething(a, b);future.setHandler( ar -> { /* Completion handler */ });
REQUEST-REPLYINTERACTIONS
HTTP,TCP,RPC...
VERT.XHELLOWORLDVertx vertx = Vertx.vertx();vertx.createHttpServer() .requestHandler(request -> { // Handler receiving requests request.response().end("World !"); }) .listen(8080, ar -> { // Handler receiving start sequence completion (AsyncResult) if (ar.succeeded()) { System.out.println("Server started on port " + ar.result().actualPort()); } else { ar.cause().printStackTrace(); } });
VERT.XHELLOWORLDInvoke
EVENTLOOPS
VERT.XASYNCHTTPCLIENTHttpClient client = vertx.createHttpClient( new HttpClientOptions() .setDefaultHost("localhost") .setDefaultPort(8081));
client.getNow("/", response -> { // Handler receiving the response
// Get the content response.bodyHandler(buffer -> { // Handler to read the content });});
CHAINEDHTTPREQUESTS
Invoke
INTERACTINGWITHBLOCKINGSYSTEMS
MESSAGINGTheeventbus-thespineofVert.xapplications...
THEEVENTBUSTheeventbusisthenervoussystemofvert.x:
Allowsdifferentcomponentstocommunicateregardless
theimplementationlanguageandtheirlocationwhethertheyrunonvert.xornot(usingbridges)
Address:MessagesaresenttoanaddressHandler:MessagesarereceivedbyHandlers.
POINTTOPOINT
vertx.eventBus().send("address", "message");vertx.eventBus().consumer("address", message -> {});
PUBLISH/SUBSCRIBE
vertx.eventBus().publish("address", "message");vertx.eventBus().consumer("address", message -> {});
REQUEST/RESPONSE
vertx.eventBus().send("address", "message", reply -> {});vertx.eventBus().consumer("address", message -> { message.reply("response"); });
FROMLOCALTOCLUSTEREDVert.xinstancesformacluster
Theeventbusisdistributedonalltheclustermembers
Vertx.clusteredVertx(new VertxOptions(), result -> { if (result.failed()) { System.err.println("Cannot create a clustered vert.x : " + result.cause()); } else { Vertx vertx = result.result(); // ... }});
DISTRIBUTEDEVENTBUSAlmostanythingcansendandreceivemessages
DISTRIBUTEDEVENTBUSLet'shaveajava(Vert.x)app,andanodeappsending
datajusthere:
DISTRIBUTEDEVENTBUS
EVENTBUSCLIENTSANDBRIDGESBridges
SockJS:browser,node.jsTCP:languages/systemsabletoopenaTCPsocketStompAMQPCamel
Clients:
Go,C#,C,Python...
RELIABILITYPATTERNSDon'tbefool,bepreparedtofail
RELIABILITY
It'snotaboutbeingbug-freeorbulletproof,weahumans.
It'saboutbeingpreparedtofail,andhandlingthesefailures.
MANAGINGFAILURESDistributedcommunicationmayfail
AsyncResultletsusmanagethesefailures:doSomethingAsync(param1, param2, ar -> { if (ar.failed()) { System.out.println("D'oh, it has failed !"); } else { System.out.println("Everything fine ! "); }});
MANAGINGFAILURESAddingtimeouts
vertx.eventbus().send(..., ..., new DeliveryOptions().setSendTimeout(1000), reply -> { if (reply.failed()) { System.out.println("D'oh, he did not reply to me !"); } else { System.out.println("Got a mail " + reply.result().body()); }});
CIRCUITBREAKER
CIRCUITBREAKERcb.executeWithFallback(future -> { // Async operation client.get("/", response -> { response.bodyHandler(buffer -> { future.complete("Ola " + buffer.toString()); }); }) .exceptionHandler(future::fail) .end(); },
// Fallback t -> "Sorry... " + t.getMessage() + " (" + cb.state() + ")") // Handler called when the operation has completed .setHandler(content -> /* ... */);
CIRCUITBREAKER
Invoke
VERTICLEFAIL-OVERVerticlesarechunkofcodethatgetdeployedandrunbyVert.xVerticlescandeployotherverticlesVerticlescanbewritteninJava,Groovy,JavaScript,Ruby,Ceylon...
VERTICLEFAIL-OVERInHigh-Availabilitymode,verticlesdeployedona
nodethatcrashesareredeployedonasanenodeofthecluster.
VERTICLEFAIL-OVERInvoke
ELASTICITYPATTERNSBepreparedtobefamous
ELASTICITYPATTERNS
BALANCINGTHELOADWhenseveralconsumerslistentothesameaddress,Vert.xdispatchesthesentmessagesusingaround
robin.
So,toimprovethescalability,justspawnanewnode!
BALANCINGTHELOAD
BALANCINGTHELOADInvoke
SCALINGHTTP
WHATABOUTPERFORMANCES?
Becausewedoitwell,andwedoitfast
TECHEMPOWER-FORTUNERequest->JDBC(query)->Templateengine->
Response
THISISNOTTHEEND();ButthefirststepontheVert.xpath
HOWTOSTART?http://vertx.iohttp://vertx.io/blog/posts/introduction-to-vertx.htmlhttp://escoffier.me/vertx-hol/(HOL3180)ReactiveMicroserviceswithVert.x(CON5389)
https://jaxlondon.com/jax-awards/