Microservices with jRuby

Hubert Łępicki

@hubertlepicki

Hi Tel Aviv!

My name is Hubert

I come from

Białystok

The land of cebularz

a.k.a. Bialy

I like:

  1. Ruby
  2. Food

What will I talk about?

  • Polish cuisine
  • Ruby (on/off Rails)
  • Microservices
  • jRuby

Let's start with food

Party time at my grandpa's

Sernik

Pierogi!

BIGOS!!!

Ruby on Rails

  • Tightly integrated framework
  • Deliver prototypes very fast
  • http://canrailsscale.com/ ?
  • It's quite nice if you trim it down to API

Average 3-years-old Rails project

Layered architecture

All problems in computer science can be solved by another level of indirection

...except for the problem of too many layers of indirection.

Does it scale?

No.

Scaling Rails

  • More web server instances
  • More dynos / VPSes / physical servers
  • More memory
  • Background jobs, workers, queues

Microservices

Pierogi architecture

Scaling individual pierogi

"Mixed pierogi" plate

Microservices

  • set of small applications
  • single-responsibility principle
  • scale independently of each other
  • communicate with UI or each other
  • deployable/upgradable independently

Problems with microservices

  • how do we split the app?
  • maintaining bigger infrastructure
  • difficult system testing
  • difficult development

Microservices are like pierogi

But what you really need is bigos

jRuby has the missing cabbage 

Torquebox

  • application server
  • developed by RedHat
  • based on JBoss
  • jRuby
  • clustered
  • HornetQ
  • STOMP & Websockets

Torquebox components

Perfectly fine for deploying Rails

...but it shines with microservices

Advantages of Torquebox

  • queues and topics
  • sessions
  • cache store
  • (optionally shared)

Long-lived queues

# queues-knob.yml

queues:
  /queues/my_queue:

  /queues/my_other_queue:
    durable: false

topics:
  /topics/my_topic:

Deploying microservices

# torquebox.rb
TorqueBox.configure do |cfg|
  cfg.web do |web|
    web.context "/ping/"
  end
end

# config.ru
get '/' do
  "<html><body>Hello from Torquebox</body></html>"
end

run Sinatra::Application

Microservice Services

TorqueBox.configure do |cfg|
  cfg.service MyService
end

class MyService
  def initialize(args={}); end

  def start; Thread.new { run }; end

  def stop; @done = true; end

  def run
    until @done
      puts "Hello #{@name}"
      sleep(1)
    end
  end
end

Messaging

# publish message in some microservice
queue = TorqueBox.fetch('/queues/foo')
queue.publish "A text message"

# and process it in other microservice
message = queue.receive

Scaling some parts

TorqueBox.configure do
  ...
  pool :web do
    min 3   # min workers
    max 10  # max workers
  end
end

Moar features

  • mixing-in Java or other JVM languages
  • reverse proxy and load balancing built-in
  • JAAS Ruby bindings
  • no-op and dependency injection

For Node.js fans

vert.x

http://vertx.io

Vert.x is Node for jRuby

  • asynchronous
  • polyglot
  • framework for building servers

Verticles

require "vertx"
include Vertx

@server = NetServer.new.connect_handler 
{ |socket|
  Pump.new(socket, socket).start
}.listen(1234, 'localhost')

def vertx_stop
  @server.close
end

Verticles are microservices by nature

Scaling with vert.x

Vertx.deploy_verticle("v1.rb", cfg[:verticle1_config])
Vertx.deploy_verticle("v2.rb", cfg[:verticle2_config], 5)
Vertx.deploy_verticle("v3.rb", cfg[:verticle3_config])
Vertx.deploy_worker_verticle("v4.rb", cfg[:verticle4_config])
Vertx.deploy_worker_verticle("v5.rb", cfg[:verticle5_config], 10)

Messaging

# verticle1: send message
Vertx::EventBus.publish("test.address", 'hello world')

# verticle2: receive and reply
Vertx::EventBus.register_handler('test.address') do
|message|
  puts "I received a message #{message.body}"

  message.reply('This is a reply')
end

Torquebox vs Vert.x

  • synchronous vs asynchronous
  • heavy vs lightweight
  • websockets with stopm vs direct access to message bus (with websockets/SockJS)
  • re-use existing ecosystem and libraries vs need to build more stuff on your own

Bottom line

  • jRuby is the way to go with Ruby microservices
  • choose your tools wisely
  • no need to re-invent the wheel

Thanks!

Questions?

Find me on Twitter:

@hubertlepicki

Made with Slides.com