简体   繁体   中英

Rails pub/sub with ActiveMQ

I'd like my Rails app to be able to listen and publish to ActiveMQ queues.

This article gives examples of how to use a ruby STOMP client, and a gem activemessaging that integrates that client into a Rails app. The functionality there seems ideal, but the activemessaging gem seems to no longer be maintained.

There are lots of resources on using rabbitMQ instead of ActiveMQ, but I'm trying to improve my Rails app's integration with an existing Java stack that's already using ActiveMQ.

So does anyone know of a gem I can use to achieve similar functionality to that of the activemessaging gem? I can't find one, so failing that:

How would I initialise a Stomp client with a persistent connection to my activeMQ instance inside the context of my Rails app, such that 1) The lifecycle of the client is tied to that of the ruby process running my app, not the request-response procedure, and 2) I get to consume to messages using code such as Active Record models or service objects defined in my app?

Thanks in advance.

According to the ActiveMessaging project website :

ActiveMessaging is a generic framework to ease using messaging, but is not tied to any particular messaging system - in fact, it now has support for Stomp, AMQP, beanstalk, Amazon Simple Queue Service (SQS), JMS (using StompConnect or direct on JRuby), WebSphere MQ...

So, it's an interface to simplify integration between various messaging protocols and/or providers. However, since your using a standardized messaging protocol (ie STOMP) you don't really need it .

I recommend you simply use this STOMP gem which is referenced in the original article.

STOMP, as the name suggests, is a very simple protocol. You should be able to use it however you need in your application.

As there's so little out there on this topic I thought I'd share the solution I came up with. Having established that using the STOMP gem directly is the way forward let me re-iterate the key challenges:

How would I initialise a Stomp client with a persistent connection to my activeMQ instance inside the context of my Rails app, such that

1) The lifecycle of the client is tied to that of the ruby process running my app, not the request-response procedure, and

2) I get to consume to messages using code such as Active Record models or service objects defined in my app?

Part 1) turned out to be a bad idea. I managed to achieve this using a Rails initializer, which worked fine on my local. However, when I ran it in a staging environment I found that my message listeners died mysteriously. What seems to happen is that production web servers spawn the app (running the initializers), fork the process (without running them) and kill processes at random, eventually killing the listeners without ever having replaced them.

Instead, I used the daemons gem to create a background process that's easy to start and stop. My code in lib/daemons/message_listener.rb looked something like this:

require 'daemons'
# Usage (from daemons dir):
# ruby message_listener start
# ruby message_listener status
# ruby message_listener stop
# See https://github.com/thuehlinger/daemons for full docs.

# Require this to get your app code
require_relative '../../config/environment'

Daemons.run_proc('listener.rb') do

  client = nil

  at_exit do
    begin
      client.close
    rescue # probably means there's no connection to close, do nothing to handle it.
    end
  end

  client = Stomp::Client.new(your_config_options)

  # Your message handling code using your rails app goes here 

  loop do
    # I'd expected that subscribing to a stomp queue would be blocking,
    # but it doesn't seem to be.
    sleep(0.001)
  end

end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM