The document is a presentation by John Scattergood on building reactive microservices with JRuby and Docker. Some key points:
- Scattergood is a senior principal engineer at Autodesk who enjoys coding in languages like Java, Ruby, Groovy and JavaScript
- He will discuss running JRuby applications in production that serve millions of requests per day and building reactive systems using tools like Ratpack, Reactive Streams and Docker Swarm
- Examples are given of building reactive REST APIs, handling uneven load through backpressure, buffering and caching, and auto-scaling services using Docker and tools like Orbiter
2. § Engineer at Autodesk
§ Enjoy coding in Java, Ruby,
Groovy and JavaScript
§ Run JRuby apps in production
that serve millions of requests/day
§ First time JavaOne Speaker
@johnscattergood
About Me
7. § Dynamic
§ Object-oriented w/ first class functions
§ Expressive
§ Flexible
§ Easy to learn
Ruby
Ruby is simple in appearance, but is very complex inside just like our human body
- Yukihiro “Matz” Matsumoto
Ruby Creator
9. § Fully compatible implementation of Ruby
§ Includes benefits of JVM
§ High Performance
§ True multi-threading
§ Java libraries and interoperability
§ Standard monitoring tools
JRuby
11. § Asynchronous HTTP via Netty
§ Reactive Streams Support
§ Promises and Streams library
§ Works great with JRuby
§ Plugin Modules
§ Guice
§ Dropwizard Metrics
§ Etc.
Ratpack
15. § Cluster management with Docker Engine
§ Task Scheduling and Scaling
§ Service Discovery
§ Load Balancing
§ Automatic Restart/Recovery
§ Rolling updates
Docker Swarm Mode
16. § Cluster service that offers a REST API for scaling up and
down tasks
§ Automatically detects managed services in swarm
§ Supports
§ Preset scale increments/decrements
§ Cooldowns to avoid mistakes
Orbiter
24. § Message Passing via HTTP POST
§ Service should limit blocking as much as possible
§ Return a Receipt for long processes
§ Communicate Backpressure via Status Codes (429)
§ Client decides how to handle messages if service is
unavailable
§ Buffering
§ Dropping
Reactive REST
25. § HTTP is really nice because…
§ DNS and/or Service Discovery
§ Load Balancing
§ Transparent Scaling
§ Dynamic Routing and Proxies
Nothing wrong with Queues, but…
27. § Backpressure
§ Make the caller wait
§ Buffering
§ Accept the requests and send batches downstream
§ Caching
§ Accept the requests and send most recent downstream
Strategies
30. Buffering
chain.post(’stock') do |ctx|
buffer = ctx.get(EventBuffer.java_class)
ctx.request.body
.map { |b| JSON.parse(b.text) }
.flat_map { |event| buffer.add(event) }
.then do |buffered|
if buffered
ctx.render('OK')
else
Common::Log.debug 'backpressure!!!'
ctx.response.status(429).send
end
end
end
31. def add(event)
Promise.async do |d|
d.success(@buffer.offer(event, 1, TimeUnit::SECONDS))
end
end
def run
Execution.fork.start do |_|
get_events
.map { |events| reduce_events(events) }
.flat_map { |events| send_events(events) }
.defer(Duration.of_seconds(@backoff_duration))
.then do |responses|
responses.each { |response| handle_response(response) }
end
end
end
Buffering (contd)
49. § Joe Kutner, Deploying JRuby 9k
§ Joe Kutner, “Reactive Ruby: Building Real-time Apps with
JRuby and Ratpack”, http://blog.heroku.com
§ Dan Woods, Learning Ratpack
§ Jonas Bonér, Reactive Microservices Architecture
§ GitHub Project:
https://github.com/jscattergood/JavaOne_2017_CON3214
Further Reading