2. Nicola Ferraro - JBCNConf Barcelona 2017
About Me
Follow me on twitter:
@ni_ferraro
Nicola Ferraro
Software Engineer at Red Hat
Working on Apache Camel, Fabric8,
JBoss Fuse, Fuse Integration
Services for Openshift
3. Nicola Ferraro - JBCNConf Barcelona 2017
Agenda
● What does it mean to be reactive?
○ Reactive Programming
○ Reactive Systems
● Application Integration
○ Enterprise Integration Patterns
○ Apache Camel
● Demo
● Integration in Reactive Systems
○ Patterns
○ Future Challenges
4. Nicola Ferraro - JBCNConf Barcelona 2017
What is Reactive Programming?
The goal of your
application is to:
“put a marble into
the bucket”
Phineas and Ferb
“Chain Reaction”
Disney
5. Nicola Ferraro - JBCNConf Barcelona 2017
What is Reactive Programming?
You design all the
steps (map, flatMap,
filter, kicks and
punches) that lead to
putting a marble in
the bucket.
A fixed schema that is
activated only when a
marble is kicked in
(reactive).
A gameplay on Youtube
Phineas and Ferb “Chain Reaction”
Disney
7. Nicola Ferraro - JBCNConf Barcelona 2017
Streams vs. Request/Response
Is reactive programming only about streams?
No, but even request/response patterns are internally mapped
as sequence of events (at event loop level).
And there’s flatMap.
// for each event, call a function
// and take the results in the stream
stream.flatMap(e -> compute(e))
8. Nicola Ferraro - JBCNConf Barcelona 2017
How a “standard” application looks like?
Multiple “moving pieces”
(threads):
● Concurrency
● Resource contention
● Lock/Wait/Notify
● “One thread per request”
model
● “Thread migration” time
It is fun to play, but
inefficient!
Super Mario Bros 3
Nintendo
9. Nicola Ferraro - JBCNConf Barcelona 2017
What’s wrong with “1 thread per request”?
At some point in the past (~2011), Node.js (it was single
threaded) was faster than many (multithreaded) Java web
servers! (according to some benchmarks… also on multi-core
machines!)
How the hell was this possible?!?!?
#reqs handled per second
Higher is better!
10. Nicola Ferraro - JBCNConf Barcelona 2017
The reactor pattern (event loop)
A “Reactor”
The Simpsons
Event
Take
Execute
Handler
Reactor
And the multi-reactor
Multiple event loops, one two per physical core
(Vert.x)
leverage
asynchronous
I/O
1 thread event
per request
With no
concurrency
issues!
11. Nicola Ferraro - JBCNConf Barcelona 2017
The Golden Rule
Don’t block the event loop!
● Thread.sleep(...)
● synchronized(...)
● statement.executeQuery()
● myLongWorkflow.execute()
● outputStream.write(...)
Blocking operations can be executed
in a external thread pool.
Do not sleep!
Do not block the reactor!
Is asynchronous IO always possible at OS level? https://lwn.net/Articles/724198/
12. Nicola Ferraro - JBCNConf Barcelona 2017
What’s wrong with “1 thread per request”?
Performance comparison of
Tomcat (1 thread per request)
vs RxNetty (2015)
Reasons:
● Thread migration + context
switch
● Slower Garbage Collection
Details:
https://github.com/Netflix-Skunkworks/WSPerfLab
/blob/master/test-results/RxNetty_vs_Tomcat_Apr
il2015.pdf
13. Nicola Ferraro - JBCNConf Barcelona 2017
Limits of “1 thread per request” model
How many concurrent requests you can handle?
1 thread requires 1 MiB of stack memory by default
10k connections ~= 10 GiB of stack memory (just for the
threads)
What about the C10m problem?
http://c10m.robertgraham.com/p/manifesto.html
The
C10k
problem
14. Nicola Ferraro - JBCNConf Barcelona 2017
Reactive Programming vs. Reactive Systems
“Reactive: Readily responsive to a stimulus”, Merriam Webster
● Responsive (react to user requests):
○ Having rapid response times
● Resilient (react to failures)
○ Being responsive also in case of failures (e.g. replication, retry)
● Elastic (react to load)
○ No bottlenecks, can scale according to load
● Message driven (react to events/messages)
○ Communication based on asynchronous message passing, with location
transparency and backpressure
The reactive manifesto: http://www.reactivemanifesto.org/
15. Nicola Ferraro - JBCNConf Barcelona 2017
Reactive “packages”
PROJECT REACTOR
(v. 5)
Toolkits for building Reactive Systems Reactive Programming Frameworks
Help me to classify them ...
streams
?
16. Nicola Ferraro - JBCNConf Barcelona 2017
Agenda
● What does it mean to be reactive?
○ Reactive Programming
○ Reactive Systems
● Application Integration
○ Enterprise Integration Patterns
○ Apache Camel
● Demo
● Integration in Reactive Systems
○ Patterns
○ Future Challenges
17. Nicola Ferraro - JBCNConf Barcelona 2017
Integration
Nobody lives in isolation.
Integration is about:
● Communication (Messaging)
● Converting protocols
● Mapping Bounded Contexts
● Message Correlation
● Routing
● Flow Control
● ...
18. Nicola Ferraro - JBCNConf Barcelona 2017
The integration platform
Apache Camel is a powerful
integration framework based on
enterprise integration patterns!
More than 200 components
Can connect to any platform The new logo (proposal)
by Zoran Regvart
20. Nicola Ferraro - JBCNConf Barcelona 2017
Basic Usage
// Simple routing
from(“jms:queue/orders”)
.log(“Processing order: ${body}”)
.to(“http://myservice”)
.to(“smtp:localhost:25”);
Isn’t “.to()” close to “.map()”?
// A (not so) much complicated
// example
from(“hdfs:/home/nicola/data”)
.unmarshal().json() // json array
.split().body()
.choice()
.when(...)
.to(“jdbc:...”)
.otherwise()
.log(“Skipped ${body}”)
21. Nicola Ferraro - JBCNConf Barcelona 2017
Camel: some EIPs
Fix out of order
messages
Aggregating results in
groups
from(“...”).resequence(header(“timestamp”))...
from(“...”).aggregate(header(“orderId”))...
22. Nicola Ferraro - JBCNConf Barcelona 2017
Camel: some EIPs
Recipient list
Content Based Routing
from(“...”).recipientList(header(“recipient”))...
from(“...”).choice().when()...otherwise()
23. Nicola Ferraro - JBCNConf Barcelona 2017
Camel: some EIPs
Hystrix
Others (important!):
● Redelivery Policy: setup number of redelivery attempts and delays
● Throttler: adjust message speed for slow consumers
● Service Call: integrate with an external service registry (consul, ribbon, kubernetes)
● Load Balancer: balance load to multiple endpoints using custom strategies
from(“...”)
.hystrix()
.to(“http://service”)
.onFallback()
.transform()...
Open and close the circuit to an external service
and provide fallback responses to the client.
S1 S2
24. Nicola Ferraro - JBCNConf Barcelona 2017
Is Camel Reactive?
Camel 3.0 will have a fully reactive core.
Camel 2.20 is not fully reactive, but:
● Uses asynchronous processing by default (no 1 thread pr)
● Supports backpressure and throttling
● Has multiple components for asynchronous I/O
No event loops and reactors, but it’s fast (especially the
latest version)!
25. Nicola Ferraro - JBCNConf Barcelona 2017
The goal: create a bigger reactive system
Integration in Reactive Systems
Browser
(Vert.x)
Microservice 1
(Vert.x)
EventBus Microservice 2
(Vert.x)
Resiliency, location
transparency
MS 1 MS 2
MS 3 MS 4
Another Reactive/Non-reactive Ecosystem
Integration
Microservice Integration
Microservice
Optional
26. Nicola Ferraro - JBCNConf Barcelona 2017
Communication in Reactive Applications
Inside the JVM:
Reactive Streams
http://www.reactive-streams.org/
A specification for asynchronous stream processing with
non-blocking backpressure [?].
PROJECT REACTOR
JVM
Reactive Streams
27. Nicola Ferraro - JBCNConf Barcelona 2017
Reactive Streams Visualized
public interface Publisher<T> {
public void subscribe(Subscriber<? super T> s);
}
public interface Subscriber<T> {
public void onSubscribe(Subscription s);
public void onNext(T t);
public void onError(Throwable t);
public void onComplete();
}
public interface Subscription {
public void request(long n);
public void cancel();
}
public interface Processor<T, R> extends Subscriber<T>,
Publisher<R> {
}
Just this 4 interfaces (and the rules to use them).
Java 9 Flow API: Flow.Publisher, Flow.Subscriber, Flow.Subscription, Flow.Processor
28. Nicola Ferraro - JBCNConf Barcelona 2017
Agenda
● What does it mean to be reactive?
○ Reactive Programming
○ Reactive Systems
● Application Integration
○ Enterprise Integration Patterns
○ Apache Camel
● Demo
● Integration in Reactive Systems
○ Patterns
○ Future Challenges
29. Nicola Ferraro - JBCNConf Barcelona 2017
Demo
Use camel-reactive-streams to exchange data with a reactive
library (Vert.x → rx-java2 → Camel).
Use camel-netty-http to connect a Spring-Boot 2 (Spring 5)
WebFlux service.
Use camel-grpc to forward a stream to a remote service and
get the response stream back.
● https://github.com/nicolaferraro/reactive-demo (note: requires camel 2.20-snapshot)
PROJECT REACTOR
30. Nicola Ferraro - JBCNConf Barcelona 2017
Demo: considerations
I’ve used the generic camel-reactive-streams component but
there’s also a specific connector for Vert.x (connects
directly to the Eventbus):
// Using the camel-vertx component
from(“vertx:raw-points”)
.to(“...”)
.to(“vertx:enhanced-points”);
31. Nicola Ferraro - JBCNConf Barcelona 2017
Agenda
● What does it mean to be reactive?
○ Reactive Programming
○ Reactive Systems
● Application Integration
○ Enterprise Integration Patterns
○ Apache Camel
● Demo
● Integration in Reactive Systems
○ Patterns
○ Future Challenges
32. Nicola Ferraro - JBCNConf Barcelona 2017
Backpressure?
OP Normal Scenario
Normal operator or
boundary betweeen
reactive streams
OP
Too much water
(events)
SLOW
buffer full
pressure in the pipes (like with water!)
Backpressure
“Remember, you can’t put too much water in a nuclear reactor”, Saturday Night Live, 1984
buffer full
Backpressure
33. Nicola Ferraro - JBCNConf Barcelona 2017
Backpressure in Reactive Streams
onSubscribe(sub)
subscribe()
request(1)
onNext(“m1”)
request(2)
onNext(“m2”)
onNext(“m3”)
Publisher
Subscriber
34. Nicola Ferraro - JBCNConf Barcelona 2017
Limited Resources: microservices - no backpressure
Microservice 1
Microservice 2
Microservice 3
Microservice 4
Can’t process all events:
● Timeout
● HTTP 503
In req/resp mode,
you can do circuit
breaking.
In in-only
(streaming) mode,
you will retry
(increase load)
35. Nicola Ferraro - JBCNConf Barcelona 2017
Limited Resources: microservices with backpressure
Microservice 1
Microservice 2
Microservice 4
Microservice 3You can buffer at the
source!
Flow control at
system level
backpressure
Less responsive, but you
can handle peaks
Later, you can scale out
“Microservice 4” to make
the system more
responsive
36. Nicola Ferraro - JBCNConf Barcelona 2017
End-to-End Backpressure: In-Only Stream
Java / JS /
Python
Service 1
Java / JS /
Python
Service 2
backpressured
How???
RSocket
http://rsocket.io/
Application protocol providing reactive streams semantics.
Other solutions?? Designed for efficiency at low level
onNext
onError
onComplete
37. Nicola Ferraro - JBCNConf Barcelona 2017
End-to-End Backpressure: In-Only Stream
This backpressure stuff is not new…
38. Nicola Ferraro - JBCNConf Barcelona 2017
Back to TCP
TPC implements a sliding window protocol for flow control!
Java / JS /
Python
Java / JS /
Python
TCP / IP
data
ack + window size
You cannot send more data
than requested to a TCP
recipient!
TCP is backpressure aware!
39. Nicola Ferraro - JBCNConf Barcelona 2017
Backpressure at Application Level: In-Only Stream
App 1
TCP
Local Backpressure:
do not write too much
App 2
TCP
Local Backpressure:
do not read if can’t process
backpressured
Application Level
Backpressure
Sliding window flow control
Can work also with higher level protocols
● HTTP
● Websocket
● SSE
● gRPC End-to-end backpressure
40. Nicola Ferraro - JBCNConf Barcelona 2017
Backpressure: Stream → Camel
What in case of request/response messaging?
Reactive
Streams
Rx-Java Camel
from(“reactive-streams:events”)
.throttle(3).timePeriodMillis(10000)
.to(“http://dinosaurs.io/api/echo”);
Camel
Producer
External Servicebackpressure
from(“reactive-streams:events?maxInflightExchanges=20”)
.to(“http://dinosaurs.io/api/echo”);
No more than 20 concurrent reqsNo more than 3 reqs in 10 secs
In-Out
41. Nicola Ferraro - JBCNConf Barcelona 2017
Backpressure: Camel → Stream
Camel
Consumer
Reactive
Streams
What happens when backpressure slows down Camel?
Reactor-CoreCamel
from(“jms:events”)
.routePolicy(maxExchangesPolicy)
.to(“reactive-streams:events”);
Message Source
backpressure
Camel will pause the consumer
in case of backpressure
Flux<Message>
42. Nicola Ferraro - JBCNConf Barcelona 2017
Adding Elasticity: Load Balancer
canvas1
canvas2Camel Load Balancer:
from(“...”)
.loadBalance().sticky(canvasIdExpr())
.to(“endpoint1”, “endpoint2”)
Supports:
● Round robin, random, custom
● Failover
● Mixing with ServiceCall EIP (location transparency + load balancing) Works with any protocol:
HTTP, TCP, GRPC, ...
Streams or
RPC
43. Nicola Ferraro - JBCNConf Barcelona 2017
Adding (a bit of) Location Transparency
192.168.0.22
service-1 service-2
Service Registry
● Consul
● Etcd
● Kubernetes
● Ribbon
Camel ServiceCall EIP:
from(“...”)
.serviceCall(“service-2”)
.to(“...”)
44. Nicola Ferraro - JBCNConf Barcelona 2017
Adding Location Transparency and Resiliency
Reactive
Streams
Rx-Java Camel
Camel
Producer
Camel
Consumer
Messaging Broker
(your choice)
● JMS
● Kafka (anti-backpressure)
● AMQP
● MQTT
backpressure
Allows all kind of messaging patterns:
● P2P In-Only
● P2P In-Out
● Pub/Sub
Send messages to:
● Queues
● Topics
backpressure
If you have a fast-enough
messaging broker, you don’t have to
care a lot about backpressure when
writing (anti-backpressure)
45. Nicola Ferraro - JBCNConf Barcelona 2017
@ni_ferraro
That’s all folks!