【问题标题】:Run Ruby Task Whenever Amazon SQS Queue Is Updated每当更新 Amazon SQS 队列时运行 Ruby 任务
【发布时间】:2014-10-23 09:51:28
【问题描述】:

我最近做了很多 Sinatra,我认为是时候将它提升到一个新的水平了。任何帮助将不胜感激。所以这就是我想做的事情:

每当用户发起事件时,应用程序 A 都会向 Amazon SQS 队列抛出一个事件。每当有任何事件进入队列时,应用 B 都会执行一项任务(比如向用户发送“嘿”消息)。除了以下代码之外,我从未真正与 Cron Jobs 合作过:

$sum = 1

Thread.new do # trivial example work thread
  while true do
     sleep 3
     $sum += 1
  end
end


get '/' do
    "Testing background work thread: sum is #{$sum}"
end

感谢马克·沃森 (http://markwatson.com/blog/2011-11/ruby-sinatra-web-apps-with-background-work-threads.html)

这是我的疑问:

  • “在 Amazon Queue 更新上执行任务”是否可能?还是我想错了?
  • 如何更新上述代码,使其每 3 秒自动刷新一次,而不会出现“无限循环”错误?

【问题讨论】:

    标签: ruby cron sinatra amazon-sqs


    【解决方案1】:

    我建议您将应用程序分成两部分。一个是常规的 Sinatra Web 应用程序,另一个是某种后台工作程序。

    示例应用程序

    这是您可以使用的简单的非生产工作示例。

    创建一些常见的 boot.rb 文件,将“初始化”代码放入其中:

    require 'bundler/setup'
    
    # Use this to load my '.env' that contains AWS credentials
    require 'dotenv'; Dotenv.load
    
    # We are using Amazon Ruby SDK
    require 'aws-sdk'
    
    # We configure AWS Ruby SDK
    AWS.config(
      access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
      secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')
    )
    
    # We get SQS Web Service
    sqs = AWS::SQS.new
    
    QUEUE = sqs.queues[ENV.fetch('AWS_QUEUE_URL')]
    

    简单的 Sinatra 网络 app.rb,如果您访问 /smoke,会向您的 Amazon SQS 发送消息。

    require_relative 'boot'
    require 'sinatra'
    
    get '/smoke' do
      message = QUEUE.send_message({email: "my@email.com", at: DateTime.now}.to_json.to_s)
      "Message was sent to Amazon SQS with id #{message.id}.\n"
    end
    

    创建另一个文件 - 将其命名为 worker.rb - 它将订阅您的 Amazon SQS 队列并拉取消息。

    require_relative 'boot'
    
    QUEUE.poll do |msg|
      object = JSON.load(msg.body) rescue {}
      puts "Got your email #{object['email']} at #{object['at']}."
    end
    

    我的本​​地 .env 文件包含 SQA 队列的凭据和 URL。

    AWS_ACCESS_KEY_ID=secret
    AWS_SECRET_ACCESS_KEY=secret
    AWS_QUEUE_URL=https://sqs.us-west-1.amazonaws.com/...
    

    运行它

    然后您只需像这样启动您的 Sinatra 应用程序和工作人员

    ruby app.rb # in one terminal
    ruby worker.rb # in another terminal
    

    如果您随后访问 /smoke,您将看到类似这样的信息 - 表示该作业已被安排。

    Message was sent to Amazon SQS with id 788e5e28-8055-4c8f-bb51-c634c327a021.
    

    您会在工作终端中看到

    Got your email my@email.com at 2014-08-29T15:20:38+02:00.
    

    现在,您不必将自己限制为只有一名工作人员...您可以拥有任意数量的工作人员,默认情况下,一条消息将仅在一名工作人员上处理。这里的另一个注意事项是我们将 JSON 作为消息发送,这就是我在 worker 中使用 JSON.load 的原因。 Amazon SQS 发送/接收纯文本消息。

    【讨论】:

      【解决方案2】:

      我建议您查看Shoryuken,它位于 AWS 开发工具包之上。您可以轻松地与 Sinatra 或任何其他 Ruby 应用程序集成。

      get '/' do
        MyWorker.perform_async(msg)
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-12
        • 2016-01-18
        • 2019-04-11
        • 2014-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多