gpt4 book ai didi

ruby-on-rails - rails : How to listen to/pull from service or queue?

转载 作者:行者123 更新时间:2023-12-04 13:31:20 24 4
gpt4 key购买 nike

大多数 Rails 应用程序的工作方式是等待来自客户端的请求,然后发挥作用。
但是,如果我想使用 Rails 应用程序作为微服务架构的一部分(例如),进行一些异步通信(服务 A 将事件发送到 Kafka 或 RabbitMQ 队列,而服务 B - 我的 Rails 应用程序 - 应该监听这个队列),如何调整/启动 Rails 应用程序以立即监听队列并由那里的事件触发? (意味着初始触发器不是来自客户端,而是来自应用程序本身。)

谢谢你的建议!

最佳答案

我刚刚在我的应用程序中设置了 RabbitMQ 消息传递,并将在第二天左右实现解耦(多个、分布式)应用程序。我找到了 this文章非常有帮助(还有 RabbitMQ tutorials )。下面的所有代码都是针对 RabbitMQ 的,并且假设您有一个 RabbitMQ 服务器启动并在您的本地机器上运行。

这是我到目前为止所拥有的 - 这对我有用:

  #Gemfile
gem 'bunny'
gem 'sneakers'

我有一个 Publisher发送到队列:
  # app/agents/messaging/publisher.rb
module Messaging
class Publisher
class << self

def publish(args)
connection = Bunny.new
connection.start
channel = connection.create_channel
queue_name = "#{args.keys.first.to_s.pluralize}_queue"
queue = channel.queue(queue_name, durable: true)
channel.default_exchange.publish(args[args.keys.first].to_json, :routing_key => queue.name)
puts "in #{self}.#{__method__}, [x] Sent #{args}!"
connection.close
end

end
end
end

我像这样使用:
  Messaging::Publisher.publish(event: {... event details...})

然后我有我的“听众”:
  # app/agents/messaging/events_queue_receiver.rb
require_dependency "#{Rails.root.join('app','agents','messaging','events_agent')}"

module Messaging
class EventsQueueReceiver
include Sneakers::Worker
from_queue :events_queue, env: nil

def work(msg)
logger.info msg
response = Messaging::EventsAgent.distribute(JSON.parse(msg).with_indifferent_access)
ack! if response[:success]
end

end
end

“监听器”将消息发送到 Messaging::EventsAgent.distribute ,是这样的:
  # app/agents/messaging/events_agent.rb
require_dependency #{Rails.root.join('app','agents','fsm','state_assignment_agent')}"

module Messaging
class EventsAgent
EVENT_HANDLERS = {
enroll_in_program: ["FSM::StateAssignmentAgent"]
}
class << self

def publish(event)
Messaging::Publisher.publish(event: event)
end

def distribute(event)
puts "in #{self}.#{__method__}, message"
if event[:handler]
puts "in #{self}.#{__method__}, event[:handler: #{event[:handler}"
event[:handler].constantize.handle_event(event)
else
event_name = event[:event_name].to_sym
EVENT_HANDLERS[event_name].each do |handler|
event[:handler] = handler
publish(event)
end
end
return {success: true}
end

end
end
end

按照 Codetunes 上的说明,我有:
  # Rakefile
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

require 'sneakers/tasks'
Rails.application.load_tasks

和:
  # app/config/sneakers.rb
Sneakers.configure({})
Sneakers.logger.level = Logger::INFO # the default DEBUG is too noisy

我打开了两个控制台窗口。首先,我说(让我的听众运行):
  $ WORKERS=Messaging::EventsQueueReceiver rake sneakers:run
... a bunch of start up info
2016-03-18T14:16:42Z p-5877 t-14d03e INFO: Heartbeat interval used (in seconds): 2
2016-03-18T14:16:42Z p-5899 t-14d03e INFO: Heartbeat interval used (in seconds): 2
2016-03-18T14:16:42Z p-5922 t-14d03e INFO: Heartbeat interval used (in seconds): 2
2016-03-18T14:16:42Z p-5944 t-14d03e INFO: Heartbeat interval used (in seconds): 2

第二,我说:
  $ rails s --sandbox
2.1.2 :001 > Messaging::Publisher.publish({:event=>{:event_name=>"enroll_in_program", :program_system_name=>"aha_chh", :person_id=>1}})
in Messaging::Publisher.publish, [x] Sent {:event=>{:event_name=>"enroll_in_program", :program_system_name=>"aha_chh", :person_id=>1}}!
=> :closed

然后,回到我的第一个窗口,我看到:
  2016-03-18T14:17:44Z p-5877 t-19nfxy INFO: {"event_name":"enroll_in_program","program_system_name":"aha_chh","person_id":1}
in Messaging::EventsAgent.distribute, message
in Messaging::EventsAgent.distribute, event[:handler]: FSM::StateAssignmentAgent

在我的 RabbitMQ 服务器中,我看到:

enter image description here

这是一个非常简单的设置,我相信在 future 几天我会学到更多。

祝你好运!

关于ruby-on-rails - rails : How to listen to/pull from service or queue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36080524/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com