为什么我的AMQP消息会在发送之前进行调整

时间:2012-01-13 23:43:13

标签: ruby rabbitmq amqp

我遇到的问题是,在另一个消费者收到消息之前,将大约20封AMQP消息发布到RabbitMQ中的共享队列会被批量延迟。我的应用程序拓扑有三个端点:

  1. 第一个端点将生成一批消息,每个消息都包含要从中收集配置文件的网络设备的FQDN。将有一个此端点的实例,并且是名为net.svc.ssh的直接队列的唯一发布者。
  2. 第二个端点将使用其中一条消息,SSH到指定的网络设备,运行CLI命令并将结果从每个设备发布到另一个队列。将有多个此端点的实例,所有这些实例都使用net.svc.ssh并发布到net.svc.savefile。
  3. 第三个端点将收到该结果,并将其保存到自己单独文件中的本地磁盘。此实例是net.svc.savefile的唯一使用者,并且不发布任何消息。
  4. 我看到的是,所有第二个端点都将“保持”其传出消息,直到没有消息从ssh队列中消耗掉。这可以防止将设备配置及时传送到最终端点。我所观察到的是,一旦所有中间端点消耗了他们的消息,每个配置都会同时进入。

    所以我的问题是为什么我会看到这种假脱机行为?我希望我们的消息在它们准备好的那一刻就被发布,并且这种行为不是预期的。

    端点1 - 网络设备备份请求的发送方:

    EventMachine.add_timer( 0 ) do
      YAML::load_file( 'hosts.yaml' ).each do |fqdn,ip|
        payload = { :fqdn => fqdn }
        exchange.publish( payload.to_json, :routing_key => 'net.svc.ssh' )
      end
    end
    

    端点2 - ssh节点

    mq_queue.subscribe( :ack => false ) do |meta, mq_payload|
      payload = JSON.parse( mq_payload)
    
      # SSH stuff happens here
    
      mq_channel.default_exchange.publish( payload.to_json,
                                           :routing_key => 'net.svc.savefile',
                                           )
      end
    end
    

    端点3 - 将设备配置保存到文件

    的节点
    queue.subscribe( ) do |meta, mq_payload|
      payload = JSON.parse( mq_payload )
      payload[ "host" ].each do |host,hash|
        File.open( File.join('backups', host), "w" ) do |file|
          result = hash[ "result" ]
          if( result[ "error" ].nil? )
            file << result[ "show running-config" ].join( "\n" )
          else
            file << result[ "error" ]
          end
        end
      end
    end
    

1 个答案:

答案 0 :(得分:1)

在我看来,您正在使用默认行为向主题交换发布消息。我假设你的消费者(有多个实例)订阅了一个队列,路由密钥上有一个简单的绑定,即多个消费者将循环播放消息。

或者也许只有一个消费者。

我多年没有使用Ruby了,所以我不熟悉各种库的怪癖,但是在看到消息后,我无法看到消费者对消息的确认。在消费者2上,你似乎已经明确地将auto-ack设置为FALSE,这很好,而在消费者3中你没有设置它,所以也许这意味着auto-ack正在发生。

当我编写一个在另一个队列上发布结果的消费者时,我按此顺序执行操作:

  1. 获取传入消息
  2. 做好工作
  3. 将新邮件发布到结果队列
  4. 确认收到的消息