torquebox for rubyists

84
TorqueBox Enterprise-Grade Ruby Application Server Bob McWhirter Asheville.rb Asheville, North Carolina 2 December 2009 Creative Commons BY-SA 3.0

Upload: bobmcwhirter

Post on 06-May-2015

1.894 views

Category:

Technology


1 download

DESCRIPTION

Presentation of TorqueBox for Rubyists at Asheville.rb

TRANSCRIPT

Page 1: TorqueBox for Rubyists

TorqueBoxEnterprise-Grade Ruby Application ServerBob McWhirter

Asheville.rbAsheville, North Carolina

2 December 2009

Creative Commons BY-SA 3.0

Page 2: TorqueBox for Rubyists

Bob McWhirter

• Started in C++

• Moved to Java with JDK 1.1.8

• Began Ruby and Rails in 2005

• Lived in Asheville for 4 years

• Did some open-source along the way

2

Page 3: TorqueBox for Rubyists

Open-Source

3

Page 4: TorqueBox for Rubyists

Currently

4

Bob

Java

Linux

+

+

Page 5: TorqueBox for Rubyists

5

== Ruby?

Page 6: TorqueBox for Rubyists

Actual R&D

6

I get to actually research things, and develop new stuff. Honest-to-goodness technology R&D investment.

Page 7: TorqueBox for Rubyists

TorqueBox

7

...in a nutshell

Page 8: TorqueBox for Rubyists

What is it?

A merging of the Ruby language with the Java Virtual Machine.

8

Page 9: TorqueBox for Rubyists

Why bother?

As Ruby matures, it’s quickly being used to solve larger, more difficult problems.

Problems we’ve solved in the enterprise with Java already.

9

Page 10: TorqueBox for Rubyists

Such as...?

• Scalability

• Efficient & asynchronous messaging

• Scheduled jobs

• Telephony

10

Page 11: TorqueBox for Rubyists

Scalability...because “Rails doesn’t scale”

11

Page 12: TorqueBox for Rubyists

Web Scalability

12

Page 13: TorqueBox for Rubyists

mongrel-style

13

Ruby

mongrel

Page 14: TorqueBox for Rubyists

mongrel-style

14

Ruby

mongrel

Ruby

mongrel

Ruby

mongrel

Ruby

mongrel

httpd

Page 15: TorqueBox for Rubyists

mongrel-style

15

Ruby

mongrel

Ruby

mongrel

Ruby

mongrel

Ruby

mongrel

httpd

Page 16: TorqueBox for Rubyists

passenger style

16

Rails

Rails

Rails

Rails

RubyPassengerhttpd

Conservative Spawning

Page 17: TorqueBox for Rubyists

passenger style

17

Worker

Worker

Worker

Worker

RailsRubyPassengerhttpd

Smart Spawning

Page 18: TorqueBox for Rubyists

TorqueBox style

18

RailsRuby

TorqueBox

http

queues

scheduler

MyApp

Page 19: TorqueBox for Rubyists

Clustering

19

Multiplicity rocks.

Page 20: TorqueBox for Rubyists

Concerns

When clustering, we care about sessions and load balancing.

20

Page 21: TorqueBox for Rubyists

Sessions

With multiple application servers, sessions must be shared, or session affinity must be used.

21

Page 22: TorqueBox for Rubyists

Session Sharing

Sharing sessions requires using a central store, such as memcached or ActiveRecord session stores.

22

Page 23: TorqueBox for Rubyists

Session Sharing

23

memcached

Worker

Worker

Worker

Worker

Page 24: TorqueBox for Rubyists

Session Sharing

24

But what if the central session store is unavailable, or overwhelmed?

Single point of failure!

Page 25: TorqueBox for Rubyists

Session Sharing

25

memcached

Worker

Worker

Worker

Worker

Page 26: TorqueBox for Rubyists

Session Affinity

26

Session affinity is making sure the same back-end server handles all of Todd’s requests.

Page 27: TorqueBox for Rubyists

Todd’sserver

Session Affinity

27

Worker

Worker

Worker

Worker

BalancerTodd

Page 28: TorqueBox for Rubyists

Session Affinity

28

But what if the back-end server handling Todd’s requests becomes unavailable?

Page 29: TorqueBox for Rubyists

Session Affinity

29

Worker

Worker

Worker

Worker

Balancer

Todd’sserver

Todd

Page 30: TorqueBox for Rubyists

Use Both!

30

Use session affinity when you can, but allow workers to replicate session information when necessary.

Page 31: TorqueBox for Rubyists

Use Both!

31

Cache

Cache

Cache

CacheWorker

Worker

Worker

Worker

Balancer

Page 32: TorqueBox for Rubyists

Spanning Hosts

32

Host

Host

Host

Host

Cache

Cache

Cache

CacheWorker

Worker

Worker

Worker

Balancer

Page 33: TorqueBox for Rubyists

Balancer in the cluster

33

Using mod_cluster for Apache httpd, the balancer participates in the cluster view.

Page 34: TorqueBox for Rubyists

mod_cluster

As server nodes join and leave the cluster, the balancer (mod_cluster) is aware of these changes.

34

Page 35: TorqueBox for Rubyists

mod_proxy_ajp

The Apache JServ Protocol (AJP) is an efficient pipeline for shuffling HTTP requests to a Java application-server for handling.

35

Page 36: TorqueBox for Rubyists

Oh yeah...

• Multiple apps per server or cluster.

• Virtual-host support baked in.

• Context-path support.

• Full Rack support (bare, Sinatra, etc).

• Full Java-EE stack.

36

Page 37: TorqueBox for Rubyists

And bundles

myapp.rails myapp.rack

37

Page 38: TorqueBox for Rubyists

And bundles

Single ZIP file bundle of an app. Easily move specific artifact between staging and production.

Required for cluster auto-farming deployment.

38

Page 39: TorqueBox for Rubyists

Rails scales!...but there’s more than just port 80.

39

Page 40: TorqueBox for Rubyists

Task QueuesSimply install Erlang, set up RabbitMQ, use an AMQP gem...

40

Page 41: TorqueBox for Rubyists

Or just use TorqueBox...and just write a Ruby class.

41

Page 42: TorqueBox for Rubyists

app/queues/**_queue.rb

• A class per queue.

• A method per task handled by the queue.

• A simple API to toss stuff around.

42

Page 43: TorqueBox for Rubyists

my_first_queue.rb

class MyFirstQueue

include TorqueBox::Queues::Base

def task_one(payload={})

o = Thing.find_by_id( payload[:thing_id] )

o.frob!

o.save!

end

end

43

Page 44: TorqueBox for Rubyists

my_first_queue.rb

class MyFirstQueue

include TorqueBox::Queues::Base

def task_one(payload={})

o = Thing.find_by_id( payload[:thing_id] )

o.frob!

o.save!

end

end

44

Page 45: TorqueBox for Rubyists

my_first_queue.rb

class MyFirstQueue

include TorqueBox::Queues::Base

def task_one(payload={})

o = Thing.find_by_id( payload[:thing_id] )

o.frob!

o.save!

end

end

45

Page 46: TorqueBox for Rubyists

my_first_queue.rb

class MyFirstQueue

include TorqueBox::Queues::Base

def task_one(payload={})

o = Thing.find_by_id( payload[:thing_id] )

o.frob!

o.save!

end

end

46

Page 47: TorqueBox for Rubyists

my_first_queue.rb

class MyFirstQueue

include TorqueBox::Queues::Base

def task_one(payload={})

o = Thing.find_by_id( payload[:thing_id] )

o.frob!

o.save!

end

end

47

Page 48: TorqueBox for Rubyists

Enqueue

TorqueBox::Queues.enqueue( ‘MyFirstQueue’, :task_one, { :thing_id=>42 })

48

Page 49: TorqueBox for Rubyists

Enqueue

TorqueBox::Queues.enqueue( ‘MyFirstQueue’, :task_one, { :thing_id=>42 })

49

Page 50: TorqueBox for Rubyists

Enqueue

TorqueBox::Queues.enqueue( ‘MyFirstQueue’, :task_one, { :thing_id=>42 })

50

Page 51: TorqueBox for Rubyists

Enqueue

TorqueBox::Queues.enqueue( ‘MyFirstQueue’, :task_one, { :thing_id=>42 })

51

Page 52: TorqueBox for Rubyists

Enqueue

Use from your controllers, ActiveRecord observers, or other queues.

52

Page 53: TorqueBox for Rubyists

Enqueueclass User < ActiveRecord::Base has_attached_file :avatar, ... after_save do |user| TorqueBox::Queues.enqueue( :image_processor_queue, :process_user_avatar, user.id ) if user.avatar_needs_processing? endend

53

Page 54: TorqueBox for Rubyists

Enqueueclass User < ActiveRecord::Base has_attached_file :avatar, ... after_save do |user| TorqueBox::Queues.enqueue( :image_processor_queue, :process_user_avatar, user.id ) if user.avatar_needs_processing? endend

54

Page 55: TorqueBox for Rubyists

Enqueueclass User < ActiveRecord::Base has_attached_file :avatar, ... after_save do |user| TorqueBox::Queues.enqueue( :image_processor_queue, :process_user_avatar, user.id ) if user.avatar_needs_processing? endend

55

Page 56: TorqueBox for Rubyists

Enqueueclass User < ActiveRecord::Base has_attached_file :avatar, ... after_save do |user| TorqueBox::Queues.enqueue( :image_processor_queue, :process_user_avatar, user.id ) if user.avatar_needs_processing? endend

56

Page 57: TorqueBox for Rubyists

Queue Benefits

• No additional systems or languages to setup and maintain.

• Clustering/HA available (including durable messages).

• No explicit queue configuration required.

57

Page 58: TorqueBox for Rubyists

Scheduled JobsJust write a script, and a crontab, and deploy it with your app. Don’t forget to undeploy and update it also. And check cron.log for errors.

58

Page 59: TorqueBox for Rubyists

Or just use TorqueBox...and just write a Ruby class.

59

Page 60: TorqueBox for Rubyists

app/jobs/**.rb

• A class per queue.

• A method called run()

• Configure it via jobs.yml

60

Page 61: TorqueBox for Rubyists

my_first_job.rbclass MyFirstJob include TorqueBox::Jobs::Base

def run() subscriptions = Subscription.find(:all) subscriptions.each do |e| send_newsletter( e ) end endend

61

Page 62: TorqueBox for Rubyists

my_first_job.rbclass MyFirstJob include TorqueBox::Jobs::Base

def run() subscriptions = Subscription.find(:all) subscriptions.each do |e| send_newsletter( e ) end endend

62

Page 63: TorqueBox for Rubyists

my_first_job.rbclass MyFirstJob include TorqueBox::Jobs::Base

def run() subscriptions = Subscription.find(:all) subscriptions.each do |e| send_newsletter( e ) end endend

63

Page 64: TorqueBox for Rubyists

my_first_job.rbclass MyFirstJob include TorqueBox::Jobs::Base

def run() subscriptions = Subscription.find(:all) subscriptions.each do |e| send_newsletter( e ) end endend

64

Page 65: TorqueBox for Rubyists

config/jobs.yml

subscription.mailer: description: send out newsletters job: MyFirstJob cron: 20 7 1 * * ?

65

Page 66: TorqueBox for Rubyists

config/jobs.yml

subscription.mailer: description: send out newsletters job: MyFirstJob cron: 20 7 1 * * ?

66

Page 67: TorqueBox for Rubyists

config/jobs.yml

subscription.mailer: description: send out newsletters job: MyFirstJob cron: 20 7 1 * * ?

67

Page 68: TorqueBox for Rubyists

config/jobs.yml

subscription.mailer: description: send out newsletters job: MyFirstJob cron: 20 7 1 * * ?

68

Page 69: TorqueBox for Rubyists

config/jobs.yml

subscription.mailer: description: send out newsletters job: MyFirstJob cron: 20 7 1 * * ?

69

Page 70: TorqueBox for Rubyists

config/jobs.yml

20 7 1 * * ?

70

secmin

hourd.o.m.

mond.o.y

Page 71: TorqueBox for Rubyists

config/jobs.yml

20 7 1 * * ?

71

Every day,

at 1:07:20 am

Page 72: TorqueBox for Rubyists

• Uses existing Ruby interpreter when jobs fire. No waiting for Ruby/Rails to load.

• No external system (crontab) to maintain.

• No additional daemons to monitor (daemonize)

• Full Rails environment (AR models, queues, lib/)

72

Scheduler Benefits

Page 73: TorqueBox for Rubyists

TelephonyJust... um... something... with Asterisk?

73

Page 74: TorqueBox for Rubyists

Or just use TorqueBox...and just write a Ruby class.

74

Page 75: TorqueBox for Rubyists

Initiate Calls

By doing SIP magic, your application can initiate calls, or connect multiple parties.

75

Page 76: TorqueBox for Rubyists

Press 2 to STFU

Using the Media Server, automated messages, interactive voice response (IVR) and other advanced systems can be built.

76

Page 77: TorqueBox for Rubyists

OMGWTFBBQPONIES!

Have your app (for instance, upon

successful job completion) fire off an SMS.

77

Page 78: TorqueBox for Rubyists

Telephony Benefits

•It’s just freakin’ cool.

78

Page 79: TorqueBox for Rubyists

ManageabilityOkay, sorta speculative, forward-looking dreaming, but...

79

Page 80: TorqueBox for Rubyists

Manageable

Everything ultimately maps to a managed object within the Java application-server.

We have the JOPR management console.

80

Page 81: TorqueBox for Rubyists

But not yet

But we haven’t exposed everything in a super nice fashion. Yet.

81

Page 82: TorqueBox for Rubyists

All-in-OneEverything’s in the tin.Everything works together.

82

Page 83: TorqueBox for Rubyists

More information...http://torquebox.org/

http://github.com/torquebox

http://twitter.com/torquebox

83

Page 84: TorqueBox for Rubyists

Thanks +

Q&A

84Creative Commons BY-SA 3.0