98
TorqueBox The expressiveness of Ruby The power of Java Bob McWhirter JBoss Fellow

TorqueBox at DC:JBUG - November 2011

Embed Size (px)

DESCRIPTION

Presentation about TorqueBox to the DC:JBUG in November, 2011.

Citation preview

Page 1: TorqueBox at DC:JBUG - November 2011

TorqueBoxThe expressiveness of Ruby

The power of Java

Bob McWhirterJBoss Fellow

Page 2: TorqueBox at DC:JBUG - November 2011

Bob McWhirter‣ JBoss Fellow at Red Hat

‣ Founder of...

‣ The Codehaus

‣ Drools

‣ TorqueBox

‣ DeltaCloud API

Page 3: TorqueBox at DC:JBUG - November 2011

but it’s a team

Page 4: TorqueBox at DC:JBUG - November 2011

What is TorqueBox?

TorqueBox glues JRuby to the JBoss Java Application Server (JBoss AS).

Page 5: TorqueBox at DC:JBUG - November 2011

‣ Real threads

‣Many garbage-­collection options

‣ Lots of JVM research

‣ Integration with Java

‣ Fast!

Why JRuby

Page 6: TorqueBox at DC:JBUG - November 2011

What is JBoss AS?

JBoss AS is full JavaEE application server, providing web, caching, messaging, clustering, failover, etc.

Page 7: TorqueBox at DC:JBUG - November 2011

TorqueBoxCore

TorqueBoxCore

Java Virtual Machine

Managed Services ContainerJRuby with JIT

Security

Transactions

JBoss Web

Infinispan

HornetQ

Quartz

PicketLink

Rack

Sinatra Rails

Daemons

WebSocketsSTOMP

Tasks

Jobs

MessageProcessors

POJO

Spring

REST

JMS

Servlet

JavaEE

Messaging

Cache

Ruby!APIs!/!Programming!Models Java!APIs!/!Programming!Models

Polyglot Injection

Java!Enterprise!ServicesJRuby!Component!Deployers!&!Gems

Page 8: TorqueBox at DC:JBUG - November 2011

But Java is enterprisey, while Ruby is agile...!

Page 9: TorqueBox at DC:JBUG - November 2011

“Java is a DSL for taking large XML files and converting them to stack traces”

Scott Bellware

Page 10: TorqueBox at DC:JBUG - November 2011

XML means we’ve

<failed/>

One of our mantras:

Page 11: TorqueBox at DC:JBUG - November 2011

Be a great traditional Ruby environment

‣Rack

‣Rails

‣Sinatra

‣Padrino

First Order Goals

Page 12: TorqueBox at DC:JBUG - November 2011

‣ Services‣ Jobs‣ Messaging‣ Transactions

‣ Caching‣ WebSockets‣ HA/Failover

Second Order Goals

Be better than a traditional environment:

Page 13: TorqueBox at DC:JBUG - November 2011

First: web

Page 14: TorqueBox at DC:JBUG - November 2011

myapp/ config.ru config/ application.rb database.yml torquebox.yml app/ views/ controllers/ models/

Your app

Page 15: TorqueBox at DC:JBUG - November 2011

config/torquebox.yml

application: root: /path/to/myapp

web: context: / host: www.myapp.com

environment: RAILS_ENV: production MAIL_HOST: mail.myapp.com

1 AS, many apps

Page 16: TorqueBox at DC:JBUG - November 2011

WEB-­INF/web.xml<?xml version="1.0" encoding="UTF-­8"?><web-­app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-­instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-­app_2_5.xsd">

<context-­param> <param-­name>mail.host</param-­name> <param-­value>mail.myapp.com</param-­value> </context-­param>

<servlet> <display-­name>Servlet1</display-­name> <servlet-­name>Servlet1</servlet-­name> <servlet-­class>test.Servlet1</servlet-­class> </servlet>

<servlet-­mapping> <servlet-­name>Servlet1</servlet-­name> <url-­pattern>/Servlet1</url-­pattern> </servlet-­mapping>

<welcome-­file-­list> <welcome-­file>index.html</welcome-­file> </welcome-­file-­list>

</web-­app>

Compare to...

Page 17: TorqueBox at DC:JBUG - November 2011

Make Love, not WAR

Live, where it sits on disk.

No archive required.

Page 18: TorqueBox at DC:JBUG - November 2011

(caveat)

Requires runtime reloading support in your framework, but not redeployment.

Rails Rack::Reloader

Page 19: TorqueBox at DC:JBUG - November 2011

Works as expected,almost

boring

http://www.flickr.com/photos/djbadly/2052098189/

Page 20: TorqueBox at DC:JBUG - November 2011

servicesSecond order goal:

Page 21: TorqueBox at DC:JBUG - November 2011

start()

...time passes...

stop()

Daemons!

Page 22: TorqueBox at DC:JBUG - November 2011

app/services/my_service.rbclass MyServer

def initialize(opts) end

def start end

def stop end

end

Example service

Page 23: TorqueBox at DC:JBUG - November 2011

config/torquebox.ymlService config

services:

MyService: some_key: some_value

MyCriticalService: singleton: true

Page 24: TorqueBox at DC:JBUG - November 2011

singleton?

true

Ensures one (and only one) instance is running within the cluster at a time, with failover.

Page 25: TorqueBox at DC:JBUG - November 2011

singleton?

false(default)

Page 26: TorqueBox at DC:JBUG - November 2011

scheduled jobsSecond order goal:

Page 27: TorqueBox at DC:JBUG - November 2011

-­every 3 hours...-­ the first of each month...-­on Tuesdays...-­when the world ends...

cron-­like

http://www.flickr.com/photos/spine/2408967576/

Page 28: TorqueBox at DC:JBUG - November 2011

apps/jobs/my_job.rbJob example

class MyJob def run()

# your code here

end

end

Page 29: TorqueBox at DC:JBUG - November 2011

config/torquebox.ymlJob config

jobs: monthly_reminder: description: sends reminders job: MyJob cron: ‘0 0 0 1 * ?’ singleton: true

file_cleaner: description: clean files on node job: FileCleaner cron: ‘5 * * * * ?’

Page 30: TorqueBox at DC:JBUG - November 2011
Page 31: TorqueBox at DC:JBUG - November 2011

messagingmessaging

messaging

Second order goal:

(we really like messaging)

Page 32: TorqueBox at DC:JBUG - November 2011

Darn zippy JMS broker

Page 33: TorqueBox at DC:JBUG - November 2011

config/torquebox.yml

queues: /queues/puppies: /queues/kittens: durable: false

topics: /topics/memes:

Where to, my friend?

Page 34: TorqueBox at DC:JBUG - November 2011

Topic Queue

Consumer Consumer Consumer Consumer

Page 35: TorqueBox at DC:JBUG - November 2011

arbitrary_app_stuff.rbLet’s go!

class MyController < ApplicationController

include TorqueBox::Injectors

def index @queue = inject( ‘/queues/puppies’ ) @queue.publish( “Oh, puppies!” ) end

end

Page 36: TorqueBox at DC:JBUG - November 2011

app/processors/my_processorNow arriving...

include TorqueBox::Messaging

class MyProcessor < MessageProcessor

def initialize(opts) end

def on_message(body) # your code here. end

end

Page 37: TorqueBox at DC:JBUG - November 2011

config/torquebox.ymlProcessor config

messaging: /queues/puppies: MyHandler: concurrency: 5 config: some_key: some_value

/queues/kittens: MyOtherHandler: singleton: true

Page 38: TorqueBox at DC:JBUG - November 2011

But that’s not all!

Page 39: TorqueBox at DC:JBUG - November 2011

What makes messaging special?

Page 40: TorqueBox at DC:JBUG - November 2011

Async

http://www.flickr.com/photos/photogaby/4129740673/

Page 41: TorqueBox at DC:JBUG - November 2011

Backgroundables

Go asynchronous without having to think about messaging.

Page 42: TorqueBox at DC:JBUG - November 2011

my_arbitrary_file.rbEnabling

class User

include TorqueBox::Messaging::Backgroundable

def do_something_slowly() upload_over_300baud_modem() end

end

Page 43: TorqueBox at DC:JBUG - November 2011

What?

Teaches your class how to invoke methods across an implicit queue.

Yay mix-­ins!

Page 44: TorqueBox at DC:JBUG - November 2011

my_other_arbitrary_file.rbUsing explicitly

u = User.new

u.do_something_slowly()

u.background.do_something_slowly()

Page 45: TorqueBox at DC:JBUG - November 2011

my_arbitrary_file.rbForcing

class User

include TorqueBox::Messaging::Backgroundable always_background :do_something_slowly

def do_something_slowly() upload_over_300baud_modem() end

end

Page 46: TorqueBox at DC:JBUG - November 2011

my_other_arbitrary_file.rbUsing implicitly

u = User.new

u.do_something_slowly()

Page 47: TorqueBox at DC:JBUG - November 2011

The FUTURE!future = user.do_something_slowly()

future.started?

future.complete?

future.error?

future.result

Page 48: TorqueBox at DC:JBUG - November 2011

Progress!class User

include TorqueBox::Backgroundable always_background :do_something_slowly

def do_something_slowly upload_over_modem() future.status = “uploaded”

alert_authorities future.status = “alerted” endend

Page 49: TorqueBox at DC:JBUG - November 2011

Query

future = user.do_something_slowly()

future.status_changed?

future.status # => “uploaded”

Page 50: TorqueBox at DC:JBUG - November 2011

transactionsSecond order goal:

Page 51: TorqueBox at DC:JBUG - November 2011

Queue Database Infinispan

TopicYour!Code

Transactions

Page 52: TorqueBox at DC:JBUG - November 2011

Queue Database Infinispan

TopicYour!Code[ ]XA distributed, multi-­resource transaction

Transactions

Page 53: TorqueBox at DC:JBUG - November 2011

XA

‣ HornetQ supports XA

‣ Infinispan supports XA

‣ TorqueBox makes ActiveRecord support XA, if your database does.

Everything succeeds or everything fails

Page 54: TorqueBox at DC:JBUG - November 2011

cachingSecond order goal:

and more

Page 55: TorqueBox at DC:JBUG - November 2011

Infinispan

Node Node Node Node

Item #1 Item #1Item #2

Item #2Item #3

Item #3Item #4Item #4

Replicated & Distributed

Page 56: TorqueBox at DC:JBUG - November 2011

Places Rails can use memcached?

Now you’re using Infinispan.

Replace memcached

Page 57: TorqueBox at DC:JBUG - November 2011

As an object-­store

Usable behind DataMapper through

dm-­infinispan-­adapter.

Page 58: TorqueBox at DC:JBUG - November 2011

my_arbitrary_file.rbDirectly

my_cache = TorqueBoxStore.new( :name=>‘my-­cache’, :mode=>:replicated )

my_cache.put(...)my_cache.get(...)

Page 59: TorqueBox at DC:JBUG - November 2011

Clustered web sessions...

Page 60: TorqueBox at DC:JBUG - November 2011

websocketsSecond order goal:

Page 61: TorqueBox at DC:JBUG - November 2011

Stream-­Oriented Message Protocol

to the browser

(I did say we really really liked messaging)

Page 62: TorqueBox at DC:JBUG - November 2011

Bare WebSockets and clusters don’t get along.

http://www.flickr.com/photos/greencolander/4299692892/

Page 63: TorqueBox at DC:JBUG - November 2011

WebSockets is already frame-­based, not streaming...

Use messaging!

Page 64: TorqueBox at DC:JBUG - November 2011

But directly exposing your JMS to the internet seems unwise...

http://www.flickr.com/photos/ell-­r-­brown/4686613540/

Page 65: TorqueBox at DC:JBUG - November 2011

Stomplets act as a controller between user and JMS.

Page 66: TorqueBox at DC:JBUG - November 2011

Browser Stomplet JMS!Stuff

Page 67: TorqueBox at DC:JBUG - November 2011

app/stomplets/my_stomplet.rbclass MyStomplet

def on_subscribe(subscriber) end

def on_unsubscribe(subscriber) end

def on_message(stomp_message, session) end

end

Example Stomplet

Page 68: TorqueBox at DC:JBUG - November 2011

config/torquebox.ymlConfiguration

stomp: stomplets: animals: route: ‘/animals/:type’ class: MyStomplet

Page 69: TorqueBox at DC:JBUG - November 2011

JMS helpers

subscribe_to( subscriber, jms_dest )

send_to( jms_dest, message, headers= )

Page 70: TorqueBox at DC:JBUG - November 2011

injectionSecond order goal:

Page 71: TorqueBox at DC:JBUG - November 2011

‣ Inversion of control

‣ Allows for easier testing

‣ Inject non-­Ruby things

Resource Injection

Page 72: TorqueBox at DC:JBUG - November 2011

Injectables

‣ Services

‣ Queues & Topics

‣ Java CDI components

Page 73: TorqueBox at DC:JBUG - November 2011

Destinations

inject( ‘/queues/kittens’ ).publish(...)

inject( ‘/topics/puppies’ ).publish(...)

Page 74: TorqueBox at DC:JBUG - November 2011

MyJavaThing.javaCDI

package com.mycorp;;

@ApplicationScopedpublic class MyJavaThing

public void frob() ...

Page 75: TorqueBox at DC:JBUG - November 2011

my_arbitrary_file.rbCDI

inject( com.mycorp.MyJavaThing ).frob()

Page 76: TorqueBox at DC:JBUG - November 2011

Clustering

Page 77: TorqueBox at DC:JBUG - November 2011

There is no cluster (noun),but things can cluster (verb).

Page 78: TorqueBox at DC:JBUG - November 2011

‣Web sessions

‣Web load-­balancing

‣ Caches

‣Messaging destinations

‣ HA coordination

Clusterstuff

Page 79: TorqueBox at DC:JBUG - November 2011

Many discovery and communication options.‣ Multicast

‣ Rendezvous

‣ S3

‣ File

JGroups

(Caveat: except

HornetQ)

Page 80: TorqueBox at DC:JBUG - November 2011

mod_cluster

httpd!+!mod_cluster

AS AS AS

Page 81: TorqueBox at DC:JBUG - November 2011

performance

Page 82: TorqueBox at DC:JBUG - November 2011

Throughput

TorqueBox

TrinidadPassengerUnicorn

0

40

80

120

40min

Higher is better

Page 83: TorqueBox at DC:JBUG - November 2011

Latency

TorqueBox

TrinidadPassengerUnicorn

64ms

256ms

1s

4s

16s

65s

40min

Lower is better

Page 84: TorqueBox at DC:JBUG - November 2011

CPU Usage

TorqueBox

TrinidadPassengerUnicorn

0

20

60

40min

Lower is better

40

80

Page 85: TorqueBox at DC:JBUG - November 2011

Free Memory

TorqueBox

TrinidadPassengerUnicorn

0

1gb

40min

Higher is better

2gb

3gb

4gb

5gb

6gb

7gb

Page 86: TorqueBox at DC:JBUG - November 2011

Management

Page 87: TorqueBox at DC:JBUG - November 2011

Managing groups of servers is orthogonal to the clustering of servers.

Page 88: TorqueBox at DC:JBUG - November 2011

Domain!Controller

Host!Controller Host!Controller

AS AS AS AS AS AS

API

API API

API API

Page 89: TorqueBox at DC:JBUG - November 2011

Ecosystem

Page 90: TorqueBox at DC:JBUG - November 2011

Backstage

Dashboard to monitor and control Ruby components.

With a RESTful API.

Page 91: TorqueBox at DC:JBUG - November 2011

StompBox

Git-­based application deployment straight to your server.

Page 92: TorqueBox at DC:JBUG - November 2011

TorqueSpec

RSpec enhancements for integration testing.

Start TorqueBox & deploy apps are part of your specs.

In-­container testing, too!

Page 93: TorqueBox at DC:JBUG - November 2011

Cloudrific!

Page 94: TorqueBox at DC:JBUG - November 2011

‣ Ruby

‣ Java

‣ PHP

‣ Python

‣ Perl

openshift.redhat.com

Page 95: TorqueBox at DC:JBUG - November 2011

‣ Multi-­tenant machines

‣ High density (let OS swap)

‣ Git-­based deployment

‣ Constrained to achieve density

‣ SELinux to secure tenants

Page 96: TorqueBox at DC:JBUG - November 2011

‣ http://torquebox.org/

‣ http://github.com/torquebox/torquebox

‣ #torquebox on Freenode

‣ @torquebox on Twitter

‣ The tall guy up front

Resources

Page 98: TorqueBox at DC:JBUG - November 2011

Hey,

thanks for having me!

http://www.flickr.com/photos/stevendepolo/4582437563/