how to bake reactive behavior into your java ee applications

Download How to bake reactive behavior into your Java EE applications

If you can't read please download the document

Upload: ondrej-mihalyi

Post on 14-Apr-2017

499 views

Category:

Software


0 download

TRANSCRIPT

PowerPoint Presentation

Click to edit Master title style

Click to edit Master title style

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline LevelClick to edit Master text stylesSecond levelThird levelFourth level

Fifth level

6/14/16

Click to edit Master title style

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline LevelClick to edit Master text stylesSecond levelThird levelFourth level

Fifth level

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline Level

Seventh Outline LevelClick to edit Master text styles

Second level

Third level

Fourth level

Fifth level

6/14/16

Click to edit Master title style

6/14/16

Click to edit the title text format

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline Level

@OMihalyi

Click to edit Master title style

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline LevelClick to edit Master text styles

6/14/16

How to bake reactive behavior into your Java EE applications

Ondrej Mihlyi@OMihalyi

Agenda

What is a reactive app

Support in Java EE 7

Java 8 joins the game

Payara Micro additions

Live demo

Common pitfalls

Ondrej Mihlyi



Web:
itblog.inginea.eu

Twitter: @OMihalyi

Payara suppor engineer

Java EE developer

Java EE lecturer

Java blogger

Scrummaster

dfds

Reactive application

Why apps are not inherently like this? - because of traditionally blocking API and monolithic architectures - because it is hard (for programmers)

Solutions - Completely new frameworks (Vert.x) - learn everything from scratch - not easy to reuse knowledge - Improve existing approaches - add non-blocking API - continuous improvements where it adds most value

Possible in Enterprise?

New tools and frameworks

High risks and costs

Fully reactive approachHigh cost of development

Harder to avoid and track bugs

Advice reactive where its worth

leave the door open for future

Java EE leaves the door open

Established and wide-spreadBuilt with resilience in mind (Transactions)

Messaging is first-class citizen (JMS)

Continuous improvementsAsynchronous API, thread-management

Scalability improvements (JCache)

Portable CDI extensions

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0 simplified API, managed executor)

Traditional approach

Request started external resource required (DB, WS, files) request external resource external resource is slow what do we do?

We SIMPLY wait

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Traditional approach

We SIMPLY waitSimple

Thread-safe

Sufficient when waiting time is negligible

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Traditional approach

Blocking calls:

JDBC:ResultSet rs = stmt.executeQuery(q);

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Traditional approach

Blocking calls:

JPA:List r = query.getResultList();Servlet:response.getWriter() .print(s);

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Traditional approach

Blocking design:Servlet filters

Interceptors

JSF lifecycle

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Spawn a separate thread

Idea: Blocking call in a new thread

Do something while waiting

Join the thread and retrieve results

Fail after timeout vs. block infinitely

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

java.util.concurrent.Future

Solution in Java world (since Java 5)

@Asynchronous methods since Java EE 6Solves the problem for fire-and-forget

Still drawbacks when result neededComplexity keep asking Are you ready?

Requires one more threadblocked when nothing to do while waiting

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

@Asynchronous

Any EJB method or all methods of an EJB

Executes in another thread in pool

Fire-and-forget with void result

Return result as a FutureFuture not efficient enough, well improve later

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

@Asynchronous - Fire-and-forget

@Asynchronousvoid fireAndForget (String message) { // long-running task}

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API in Java EE 7

AsyncContext in Servlet (since 3.0, Java EE 6)

// get context for another threadAsyncContext ctx = req.startAsync();AsyncContext .getResponse() .getOutputStream()ctx.complete();

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API in Java EE 7

AsyncContext in Servlet

AsyncContext ctx = req.startAsync();AsyncContext // build response (in any thread) .getResponse() .getOutputStream() // finish (in new thread)ctx.complete();

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API in Java EE 7

AsyncContext in ServletRequires to turn on async supportUsing @WebServlet annotation

In web.xml descriptor

@WebServlet (asyncSupported=true)

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API in Java EE 7

Async IO in Servlet 3.1 (Java EE 7)Non-blocking reading of multi-part form

Non-blocking writing of response body

Non-blocking IO in Java (NIO)to read HTML from files

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API

JAX-RS AsyncResponse @Suspended

@GETvoid get(@Suspended AsyncResponse r) // in another thread response.resume("OK");

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API

JAX-RS AsyncResponse @Suspended

void get(@Suspended AsyncResponse response) // in another threadresponse .resume("OK");

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Non-blocking API

JAX-RS async client

resourceTarget .request(MediaType.TEXT_PLAIN) .async() .get(new InvocationCallback() { });

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

CDI events + @Asynchronous

CDI events decouple componentsone-way communication

handlers triggered in the same thread

emitter is blocked

Handlers are asynchronous EJB methodstriggered in anyther thread emitter not blocked

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

@Inject Event ev; ev.fire(new MyEvent()); @Asynchronousvoid handle(@Observes MyEvent ev) { }

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Summary of approaches

Traditional blocking APIEasy to use, halts execution until finished

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Summary of approaches

Traditional blocking APIEasy to use, halts execution until finished

Asynchronous call with Futurenot blocking, +1 thread

Asynchronous call with callbackNot blocking, 1 thread at a time, callback hell

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Java 8

CompletableFuture (CompletionStage)Chain callbacks (like promises)

Execute in the same or another threadthenRun(), thenRunAsync(),

thenCompose(),

Complete execution in any thread at any timecompletableFuture.complete()

thenComposeAsync()

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

thenComposeAsync()

CompletableFuture cf = new CompletableFuture(); cf.thenComposeAsync( r -> return callThatReturnsCF(r);), executor) cf.complete(awaitResult())

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

thenComposeAsync()

cf.thenComposeAsync( r -> returnsCF(r) ), executor) .thenComposeAsync( cf.complete(r);

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Java EE + Java 8

Future CompletableFuture ?No, not compatible

Callbacks CompletableFuturecallback triggers cf.complete()

Pass CF as additional parameter

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Pass CF as additional parameter

void asyncCall(CompletableFuture cf) { cf.complete(result);}

cf = new CompletableFuture();asyncCall(cf);cf.thenComposeAsync( result -> , executor);

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Use managed executors

CF async methods use ForkJoinPoolNot managed by Java EE

Always use a managed executor

@ResourceManagedExecutorService executor;

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Other parts of being Reactive

Weve shown responsive API

The other 3 reactive concepts:Resilience

Messaging

Elasticity

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Resilience

Responsive in the face of failures

Server clusters and transaction isolation

Load balancer in front

Microservices (embedded server)

reduce single points of failure

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Payara Micro

Application server as executable JAR

Runs WAR apps from command line

automatic and elastic clustering

spawn many micro services dynamically

replication using distributed cache

shared 60MB runtime, 40MB in heap

www.payara.fish

V

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Messaging in Java EE

JMS traditional solutionTopics, Queues, Persistence, Transactional, Repeated delivery

Simplified API in Java EE 7some bioler-plate still necessary

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Why not make it even simpler?

@Inject @OutboundEvent ev;

// handle in different JVM void handle(@Observes @Inbound MyMsg ev) { }

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Payara Micro event bus

events handled by any distributed nodeAsynchronous (reactive) micro services

No need for service registry

On top of CDI events, just 2 qualifiers@Outbound event, @Inbound observer

Uses Hazelcast distributed executor

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Elasticity in Java EE

Weakest point of Java EE specsClusters do not scale dynamically

Many provider-specific solutions

JCache JSR targets Java EE 8

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

JCache

Standard Java API for caching

Distributed

API and CDI binding

Supported by many cache providers

Built in to Payara Server and Payara Micro

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

@Inject MyCache cache; value = cache.get(key); @CacheResultObject get( @CacheKey Object key)

JCache CDI binding

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

mycache.put(key, value); @CachePutvoid put( @CacheKey Object key, @CacheValue Object v) { // body can be empty }

JCache CDI binding

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Dynamic scaling

Just run repeatedly

binds to a free port to avoid port collisions

All instances autoconnect to a clusterEven across network (multicast)

java -jar payara-micro.java --deploy app.war --autoBindHttp

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Payara Micro example

web service on single node, computation service scaled to multiple nodesWeb service fires an @Outbound event

Computation started on a computation nodeSynchronisation using Jcache API

An event with result fired

Observed by web service and returned

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Fully reactive comes at a greater costDealing with threads, hard to track origin, communication overhead

Dont over-engineer, but leave doors open

Java EE enables gradual improvement

General advice

Established small costs of upgrade or redesign

Improvements simplifications (EJB3, CDI, JMS 2.0, managed executor)

Questions?

Thank you